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
Emil er databaseprofessionel med 10+ års erfaring inden for alt relateret til databaser. I årenes løb arbejdede han i IT- og finansbranchen og arbejder nu som freelancer.
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

Seneste indlæg af Emil Drkusic (se alle)
  • 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

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *