SQLShack (Dansk)
SQL Server-markører er et almindeligt emne på Internettet . Du finder forskellige meninger, hvornår du skal bruge dem, og hvornår du ikke skal gøre det. I dag vil vi også tale om dem og besvare spørgsmålet, hvornår (ikke) vi skal bruge dem.
Datamodellen og den generelle idé
I den foregående artikel Intro til SQL Server-sløjfer, vi talte om SQL Server-sløjfer, men vi har ikke brugt data fra databasen. Det var underligt, men det skulle blive meget tydeligere nu. I dag, mens vi forklarer markører, bruger vi dataene fra databasen til at vise, hvornår (ikke) markører skal bruges. Den datamodel, vi bruger, er den samme, som vi bruger i denne serie.
SQL Server understøtter 3 forskellige implementeringer af markører – Transact-SQL-markører, API-markører og Client-markører. I denne artikel vil vi fokusere på Transact-SQL-markører. Du genkender dem nemt, fordi de er baseret på DECLARE CURSOR-syntaksen.
SQL Server-markør – Introduktion
Før vi går til kode og eksempler, skal vi forklare, hvad SQL Server-markører er.
SQL Server-markøren er T-SQL-logik, som giver os mulighed for at gennemgå det relaterede forespørgselsresultat. Dette giver os mulighed for at udføre handlingerne sekventielt – f.eks. Udføre en opdatering på en enkelt række.
Nogle gange kan dette (synes at være) nyttigt, men når du arbejder med databaser, skal du ikke bruge proceduremæssige programmeringsmønstre men hold dig snarere til deklarativ programmering. En af hovedårsagerne er, at DBMSer allerede er optimeret til at udføre handlinger på datasæt, og derfor bør du ikke være den, der prøver at være “smartere end systemet”.
Det er stadig godt for at vide, hvordan de fungerer. Hvis ikke andet, måske møder du dem i den kode, du arver, og du bliver nødt til at omskrive logikken. Og inden du gør noget, skal du forstå, hvordan det fungerer.
Så hvis du har brug for markører, er dette hvad du skal vide om dem:
- Markører bruger variabler til at gemme værdier, der returneres i hver del af sløjfen. Derfor skal du ERKLÆRE alle variabler, du har brug for
- Den næste ting at gøre er at ERKLÆRE … MARKER FOR VÆLG forespørgsel, hvor du vil erklære en markør og også definere forespørgslen relateret til (udfylde) den markør
- Du ÅBNER markøren og FETCH NÆSTE fra markøren
- I WHILE-sløjfen tester du @@ FETCH_STATUS-variablen (WHILE @@ FETCH_STATUS = 0). Hvis betingelsen holder, vil du Jeg kommer ind i loop BEGIN … SLUT blok og udfør udsagn inde i den blok
- Når du har gennemgået hele resultatsættet, går du ud af loop. Du skal Lukke markøren og AFFJERNE den. Deallokering er vigtig, fordi dette skal slette markørdefinitionen og frigøre den anvendte hukommelse
SQL Server-markør – eksempler
Lad os nu se på to markøreksempler. Mens de er ret enkle, forklarer de pænt, hvordan markører fungerer.
I det første eksempel ønsker vi at få alle byers ider og navne sammen med deres relaterede landsnavne. Vi bruger PRINT-kommandoen til at udskrive kombinationer i hvert pass af sløjfen.
Brug af SQL Server-markøren og mens loop returnerede nøjagtigt det, vi har forventet – ider og navne på alle byer og relaterede lande, har vi i databasen.
Det vigtigste at nævne her er, at vi simpelthen kunne returnere dette resultatsæt ved hjælp af den originale SQL-forespørgsel gemt i DECLARE-delen af markøren, så der var ikke behov for en markør.
Vi går med endnu et eksempel. Denne gang forespørger vi databasen over informationsskemaer for at returnere de første 5 tabeller sorteret efter tabelnavn. Selvom der ikke er meget mening i at bruge en sådan forespørgsel, viser dette eksempel dig:
- Sådan forespørges databasen over informationsskemaer
- Sådan kombineres et par kommandoer / udsagn, vi har nævnt i tidligere artikler (IF… ELSE, WHILE loop, CONCAT)
Fra kodningssiden, Jeg vil gerne understrege, at denne gang har vi ikke udskrevet noget i en løkke, men snarere oprettet en streng ved hjælp af CONCAT. Vi har også brugt IF-sætningen til at teste, om vi er i første pas, og i så fald har vi ikke tilføjet “,”. Ellers tilføjede vi “,” til strengen.
Efter sløjfen har vi udskrevet resultatstrengen, lukket og dealloceret markøren.
Vi kunne opnå dette ved hjælp af STRING_AGG-funktionen. Denne er tilgængelig startende fra SQL Server 2017 og svarer til MySQL GROUP_CONCAT-funktionen.
SQL Server-markør – Hvornår (ikke) skal jeg bruge dem?
Jeg prøver at give et objektivt svar på spørgsmålet – “Hvornår skal du bruge SQL Server-markører, og hvornår ikke?” Da tingene ændrer sig i løbet af tiden, og der skal foretages forbedringer, skal der enten tages hensyn til markører eller på andre objekter, der “erstatter” dem datoen da denne artikel blev skrevet.Så lad os starte.
Du skal ikke bruge markører:
- Næsten altid 🙂 Dette lyder måske dumt, men det er sandt i de fleste tilfælde. SQL Server implementerer et stort antal objekter & funktioner, der gør præcis, hvad du sandsynligvis ville prøve at løse ved hjælp af markører. Før du beslutter dig for at gå med markøren, skal du være sikker på, at du har undersøgt nok til at konkludere, at markøren er den eneste mulige (gode) løsning. Samme står for sløjfer i databaser. I den forrige artikel, Intro til SQL Server-sløjfer, har vi brugt sløjfer, men ikke til at løbe igennem data.
Du kan bruge markører:
- Mest til databaseadministrationsopgaver som sikkerhedskopier, integritetskontrol, genopbygning af indekser
- For en gang opgaver, når du er sikker på, at mulig dårlig ydelse ikke påvirker den samlede systemydelse
-
Opkald til en gemt procedure et par gange ved hjælp af forskellige parametre. I så fald får du parametre fra markørvariabler og foretager opkald inde i sløjfen
Opkald til en lagret procedure eller en anden forespørgsel inde i markøren (eller sløjfen) påvirker ydeevnen meget, fordi i hvert trin i cursor loop, kører du forespørgslen / proceduren fra starten. Hvis du beslutter dig for at gøre det, skal du være opmærksom på mulige konsekvenser.
- Det forrige tip bringer os til den sidste kugle, når du skal bruge markører. Hvis du er helt klar over, hvordan de fungerer, og du er temmelig sikker på, at det ikke vil påvirke ydeevnen, skal du gå efter det
SQL Server-markør – hvorfor folk (ikke) bruger dem ?
Det sidste spørgsmål, jeg gerne vil besvare, er: Hvorfor bruger nogen en markør? Sådan ser jeg det:
- Folk, der bruger dem til engangsjob eller regelmæssige handlinger, hvor de ikke påvirker ydeevnen, har undskyldningen. En af grundene er, at sådan kode er procedurekode, og hvis du er vant til den, er den meget læsbar
- På den anden side kan de, der begyndte at lære om databaser og er vant til procedureprogrammering, muligvis brug markører, fordi de som sagt er meget tættere på procedureprogrammering end databaser. Dette er ikke en grund til at bruge dem, fordi den eneste undskyldning her ville være, at du simpelthen ikke kender den anden (rigtige) måde, hvordan man får tingene gjort
- Det vigtigste ved markører er, at de er langsomme sammenlignet med SQL-sætninger, og derfor bør du undgå at bruge dem, fordi de før eller senere vil føre til ydeevneproblemer (medmindre du ved præcis, hvad du laver, og hvorfor)
I find det nyttigt, at du forstår begrebet markører, fordi der er en stor chance, du møder dem undervejs. De var populære, inden nogle nye muligheder blev føjet til SQL Server. Der er også en chance for, at du fortsætter med at arbejde på et system, hvor nogen før du brugte dem, og du bliver nødt til at fortsætte, hvor de stoppede. Måske bliver du nødt til at erstatte markøren (procedurekode) med SQL (erklærende kode).
Konklusion
Der er ingen bedre konklusion om markører end – brug dem ikke 🙂 SQL Server implementerede mange ændringer, der løste problemer, der var svære at løse ved hjælp af deklarativ kode før. Bedre bruge lidt tid på at undersøge og lære noget nyt, og endelig producere optimal kode. Du kan selvfølgelig bruge dem, hvis du ved, hvorfor du gør det, og du er opmærksom på mulige problemer i forbindelse med dem.
Indholdsfortegnelse
Lær SQL : OPRET DATABASE & Opret TABELhandlinger
Lær SQL: INDSÆT I TABEL
Lær SQL: Primær nøgle
Lær SQL: Fremmed nøgle
Lær SQL: SELECT-sætning
Lær SQL: INNER JOIN vs LEFT JOIN
Lær SQL: SQL-scripts
Lær SQL: Typer af relationer
Lær SQL: Deltag i flere tabeller
Lær SQL: Samlede funktioner
Lær SQL: Hvordan man skriver en kompleks SELECT-forespørgsel?
Lær SQL: INFORMATION_SCHEMA-databasen
Lær SQL: SQL-datatyper
Lær SQL: Sæt teori
Lær SQL: Brugerdefinerede funktioner
Lær SQL: Brugerdefinerede lagrede procedurer
Lær SQL: SQL-visninger
Lær SQL: SQL-udløsere
Lær SQL: Øv SQL-forespørgsler
Lær SQL: SQL-forespørgselseksempler
Lær SQL: Opret en rapport manuelt ved hjælp af SQL-forespørgsler
Lær SQL: SQL Server dato- og tidsfunktioner
Lær SQL: Opret SQL Server-rapporter ved hjælp af dato- og tidsfunktioner
Lær SQL: SQL Server-pivottabeller
Lær SQL: SQL Server-eksport til Excel
Lær SQL: Introduktion til SQL Server-sløjfer
Lær SQL: SQL Server-markører
Lær SQL: SQL Bedste fremgangsmåder til sletning og opdatering af data
Lær SQL: Navngivningskonventioner
Lær SQL: SQL-relaterede job
Lær SQL: Ikke-Equi-sammenføjninger i SQL Server
Lær SQL: SQL Injection
- Forfatter
- Seneste indlæg
Hans tidligere og nuværende opgaver varierer fra databasedesign og kodning til undervisning, konsulentarbejde og skrivning om databaser. Også for ikke at glemme, BI, oprettelse af algoritmer, skak, filateli, 2 hunde, 2 katte, 1 kone, 1 baby …
Du kan finde ham på LinkedIn
Se alle indlæg af Emil Drkusic
- Lær SQL: SQL Injection – 2. november 2020
- Lær SQL: Non-Equi-tilslutninger i SQL Server – 29. september 2020
- Lær SQL: SQL-relaterede job – 1. september 2020