SQLShack (Svenska)
SQL Server-markörer är ett vanligt ämne på Internet . Du hittar olika åsikter när du ska använda dem och när du inte ska göra det. Idag kommer vi också att prata om dem och svara på frågan när (inte) de ska användas.
Datamodellen och den allmänna idén
I föregående artikel, Introduktion till SQL Serverslingor, vi pratade om SQL Server-loopar, men vi har inte använt data från databasen. Det var konstigt, men det borde bli mycket tydligare nu. Idag, medan vi förklarar markörer, använder vi data från databasen för att visa när (inte) markörer ska användas. Datamodellen vi använder är densamma som vi använder i denna serie.
SQL Server stöder 3 olika implementeringar av markörer – Transact-SQL-markörer, API-markörer och klientmarkörer. I den här artikeln fokuserar vi på Transact-SQL-markörer. Du kommer lätt att känna igen dem eftersom de är baserade på DECLARE CURSOR-syntaxen.
SQL Server-markör – Inledning
Innan vi går till kod och exempel bör vi förklara vilka SQL Server-markörer är.
SQL Server-markören är T-SQL-logik, vilket gör att vi kan gå igenom det relaterade frågeresultatet. Detta gör det möjligt för oss att utföra åtgärderna sekventiellt – t.ex. utföra en uppdatering på en enda rad.
Ibland kan detta (verkar) vara till hjälp, men när du arbetar med databaser ska du inte använda procedurella programmeringsmönster men håll dig snarare till deklarativ programmering. En av de främsta anledningarna är att DBMS redan är optimerade för att utföra åtgärder på datauppsättningar, och därför bör du inte vara den som försöker vara ”smartare än systemet”.
Ändå är det bra för att veta hur de fungerar. Om inget annat kanske du kommer att träffa dem i koden du ärver och du måste skriva om logiken. Och innan du gör något bör du förstå hur det fungerar.
Så om du behöver markörer är det här du borde veta om dem:
- Markörerna använder variabler för att lagra värden som returneras i varje del av slingan. Därför måste du DEKLARA alla variabler du behöver
- Nästa sak att göra är att DEKLARERA … CURSOR FOR SELECT-fråga, där du kommer att förklara en markör och även definiera frågan relaterad till (fylla i) den markören
- Du öppnar markören och FETCH NEXT från markören
- I WHILE-slingan testar du @@ FETCH_STATUS-variabeln (WHILE @@ FETCH_STATUS = 0). Om villkoret håller, kommer in i slingan BÖRJA … Sluta blockera och utföra uttalanden inuti det blocket
- När du har bläddrat igenom hela resultatuppsättningen kommer du ut ur slingan. Du bör stänga markören och avmarkera den. Omlokalisering är viktigt eftersom detta tar bort markördefinitionen och frigör det använda minne
SQL Server-markören – exempel
Låt oss nu titta på två markörexempel. Även om de är ganska enkla, förklarar de snyggt hur markörer fungerar.
I det första exemplet vill vi få alla städer id och namn tillsammans med deras relaterade landsnamn. Vi använder kommandot PRINT för att skriva ut kombinationer i varje slinga.
Med hjälp av SQL Server-markören och medan loop returnerade exakt vad vi har förväntat oss – id och namn på alla städer och relaterade länder har vi i databasen.
Det viktigaste att nämna här är att vi helt enkelt kunde returnera denna resultatsats använder den ursprungliga SQL-frågan som lagrats i DECLARE-delen av markören, så det fanns inget behov av en markör.
Vi går med ytterligare ett exempel. Den här gången frågar vi databasen över informationsscheman för att returnera de fem första tabellerna ordnade efter tabellnamn. Även om det inte är mycket meningsfullt att använda en sådan fråga, visar detta exempel dig:
- Hur man frågar informationsscheman databas
- Hur man kombinerar några kommandon / uttalanden vi har nämnts i tidigare artiklar (IF… ELSE, WHILE loop, CONCAT)
Från kodningssidan, Jag vill betona att den här gången har vi inte skrivit ut något i en slinga utan snarare skapat en sträng med CONCAT. Vi har också använt IF-uttalandet för att testa om vi är i första passet, och i så fall har vi inte lagt till ”,”. Annars skulle vi lägga till ”,” till strängen.
Efter slingan har vi skrivit ut resultatsträngen, stängt och återplacerat markören.
Vi kan uppnå detta med funktionen STRING_AGG. Den här är tillgänglig från och med SQL Server 2017 och motsvarar MySQL GROUP_CONCAT-funktionen.
SQL Server Cursor – När (Inte) för att använda dem?
Jag ska försöka ge ett objektivt svar på frågan – ”När ska du använda SQL Server-markörer och när inte”? Eftersom saker förändras under tiden och förbättringar ska göras, antingen på markörer, antingen på andra objekt som ”ersätter” dem, ta hänsyn till datumet då denna artikel skrevs.Så, låt oss börja.
Du bör inte använda markörer:
- Nästan alltid 🙂 Det här låter kanske dumt, men det är sant i de flesta fall. SQL Server implementerar ett stort antal objekt & funktioner som gör exakt vad du förmodligen skulle försöka lösa med hjälp av markörer. Innan du bestämmer dig för att följa markören, se till att du har undersökt tillräckligt för att dra slutsatsen att markören är den enda möjliga (bra) lösningen. Samma står för loopar i databaser. I den föregående artikeln Introduktion till SQL Server-slingor har vi använt slingor, men inte för att slinga igenom data.
Du kan använda markörer:
- Mestadels för databasadministrationsuppgifter som säkerhetskopior, integritetskontroller, återuppbyggnad av index
- För en gång uppgifter när du är säker på att eventuell dålig prestanda inte kommer att påverka den totala systemprestandan
-
Ringa en lagrad procedur några gånger med olika parametrar. I så fall skulle du få parametrar från markörvariabler och ringa inuti slingan
Att ringa en lagrad procedur eller en annan fråga inuti markören (eller slingan) påverkar prestanda mycket, för i varje steg i markörslinga, kör du frågan / proceduren från början. Om du bestämmer dig för att göra det bör du vara medveten om möjliga konsekvenser.
- Den föregående antydan tar oss till den sista punkten när du ska använda markörer. Om du är helt medveten om hur de fungerar och du är ganska säker på att det inte kommer att påverka prestanda, gå till det
SQL Server Cursor – Varför människor (inte) använder dem ?
Den sista frågan jag vill svara är: Varför skulle någon använda en markör? Så här ser jag det:
- Människor som använder dem för engångsjobb eller regelbundna åtgärder där de inte påverkar prestanda har ursäkten. En av anledningarna är att sådan kod är processkod, och om du är van vid den är den mycket läsbar
- Å andra sidan kan de som började lära sig om databaser och är vana vid procedurprogrammering använd markörer eftersom de, som nämnts, ligger mycket närmare procedurprogrammering än databaser. Det här är inte en anledning att använda dem, för den enda ursäkten här skulle vara att du helt enkelt inte vet det andra (rätta) sättet att få saker gjort
- Det viktigaste med markörer är att de är långsamma jämfört med SQL-uttalanden, och därför bör du undvika att använda dem eftersom de förr eller senare kommer att leda till prestandaproblem (såvida du inte vet exakt vad du gör och varför)
I tycker att det är användbart att du förstår begreppet markörer eftersom det finns en stor chans att du möter dem på vägen. De var populära innan några nya alternativ lades till SQL Server. Det finns också en chans att du fortsätter att arbeta på ett system där någon innan du använde dem, och du måste fortsätta där de slutade. Du kanske måste ersätta markören (procedurkod) med SQL (deklarativ kod).
Slutsats
Det finns ingen bättre slutsats för markörer än – använd dem inte 🙂 SQL Server implementerade många förändringar som löser problem som var svåra att lösa med hjälp av deklarativ kod tidigare. Bättre spendera lite tid på att undersöka och lära sig något nytt, och slutligen producera optimal kod. Naturligtvis kan du använda dem om du vet varför du gör det och du är medveten om möjliga problem relaterade till dem.
Innehållsförteckning
Lär dig SQL : SKAPA DATABAS & SKAPA TABELLåtgärder
Lär dig SQL: INSÄTTA I TABELL
Lär dig SQL: Primär nyckel
Lär dig SQL: främmande nyckel
Lär dig SQL: SELECT-sats
Lär dig SQL: INNER JOIN vs LEFT JOIN
Lär dig SQL: SQL-skript
Lär dig SQL: Typer av relationer
Lär dig SQL: Gå med i flera tabeller
Lär dig SQL: Aggregerade funktioner
Lär dig SQL: Hur man skriver en komplex SELECT-fråga?
Lär dig SQL: INFORMATION_SCHEMA-databasen
Lär dig SQL: SQL-datatyper
Lär dig SQL: Ställ in teori
Lär dig SQL: Användardefinierade funktioner
Lär dig SQL: Användardefinierade lagrade procedurer
Lär dig SQL: SQL-vyer
Lär dig SQL: SQL-utlösare
Lär dig SQL: Öva SQL-frågor
Lär dig SQL: SQL-frågeexempel
Lär dig SQL: Skapa en rapport manuellt med SQL-frågor
Lär dig SQL: SQL Server-datum- och tidsfunktioner
Lär dig SQL: Skapa SQL Server-rapporter med hjälp av datum- och tidsfunktioner
Lär dig SQL: SQL Server-pivottabeller
Lär dig SQL: SQL Server-export till Excel
Lär dig SQL: Introduktion till SQL Server-slingor
Lär dig SQL: SQL Server-markörer
Lär dig SQL: SQL bästa metoder för att radera och uppdatera data
Lär dig SQL: Namngivningskonventioner
Lär dig SQL: SQL-relaterade jobb
Lär dig SQL: Icke-Equi-anslutningar i SQL Server
Lär dig SQL: SQL-injektion
- Författare
- Senaste inlägg
Hans tidigare och nuvarande uppdrag varierar från databasdesign och kodning till undervisning, konsultation och skrivning om databaser. För att inte glömma, BI, skapa algoritmer, schack, filateli, 2 hundar, 2 katter, 1 fru, 1 bebis …
Du hittar honom på LinkedIn
Visa alla inlägg av Emil Drkusic
- Lär dig SQL: SQL-injektion – 2 november 2020
- Lär dig SQL: Non-Equi-anslutningar i SQL Server – 29 september 2020
- Lär dig SQL: SQL-relaterade jobb – 1 september 2020