SQLShack (Norsk)

SQL Server-markører er et vanlig tema på Internett . Du finner forskjellige meninger når du skal bruke dem og når du ikke skal gjøre det. I dag vil vi også snakke om dem og svare på spørsmålet når (ikke) vi skal bruke dem.

Datamodellen og den generelle ideen

I forrige artikkel Intro til SQL Serverløkker, vi snakket om SQL Serverløkker, men vi har ikke brukt data fra databasen. Det var rart, men det skulle bli mye tydeligere nå. I dag, mens vi forklarer markører, bruker vi dataene fra databasen for å vise når (ikke) vi bruker markører. Datamodellen vi bruker er den samme som vi bruker i hele denne serien.

SQL Server støtter 3 forskjellige implementeringer av markører – Transact-SQL-markører, API-markører og klientmarkører. I denne artikkelen vil vi fokusere på Transact-SQL-markører. Du vil lett gjenkjenne dem fordi de er basert på DECLARE CURSOR-syntaksen.

SQL Server-markør – Introduksjon

Før vi går til kode og eksempler, bør vi forklare hva SQL Server-markører er.

SQL Server-markøren er T-SQL-logikk, som lar oss gå gjennom det relaterte søkeresultatet. Dette gjør at vi kan utføre handlingene sekvensielt – for eksempel å utføre en oppdatering på en enkelt rad.

Noen ganger kan dette (synes å være) nyttig, men når du arbeider med databaser, bør du ikke bruke prosessuelle programmeringsmønstre. men hold deg heller til deklarativ programmering. En av hovedårsakene er at DBMS allerede er optimalisert for å utføre handlinger på datasett, og derfor bør du ikke være den som prøver å være «smartere enn systemet».

Likevel er det bra å vite hvordan de fungerer. Hvis ikke noe annet, kanskje du møter dem i koden du arver, og du må omskrive logikken. Og før du gjør noe, bør du forstå hvordan det fungerer.

I tilfelle du trenger markører, er det dette du bør vite om dem:

  • Markørene bruker variabler for å lagre verdier som returneres i hver del av sløyfen. Derfor må du ERKLARE alle variablene du trenger
  • Den neste tingen å gjøre er å ERKLARE… PEKER FOR VELG spørring, hvor du vil erklære en markør og også definere spørringen relatert til (fylle ut) den markøren
  • Du ÅPNER markøren og FETCH NESTE fra markøren
  • I WHILE-sløyfen vil du teste varianten @@ FETCH_STATUS (WHILE @@ FETCH_STATUS = 0). Hvis tilstanden holder, vil du Jeg går inn i loop BEGIN … SLUT blokker og utfør utsagn i den blokken
  • Etter at du har gått gjennom hele resultatsettet, går du ut av løkken. Du bør LUKKE markøren og TILKOBLE den. Omlokering er viktig fordi dette skal slette markørdefinisjonen og frigjøre minnet som brukes

SQL Server Cursor – Eksempler

La oss nå ta en titt på to markøreksempler. Mens de er ganske enkle, forklarer de pent hvordan markører fungerer.

I det første eksemplet ønsker vi å få alle byer id og navn, sammen med deres beslektede landnavn. Vi bruker PRINT-kommandoen til å skrive ut kombinasjoner i hvert pass på sløyfen.

Ved hjelp av SQL Server-markøren og mens loop returnerte akkurat det vi har forventet – IDer og navn på alle byer og relaterte land, har vi i databasen.

Det viktigste å nevne her er at vi bare kunne returnere dette resultatsettet ved hjelp av den opprinnelige SQL-spørringen som er lagret i DECLARE-delen av markøren, så det var ikke behov for en markør.

Vi går med ett eksempel til. Denne gangen vil vi spørre om databasen over informasjonsskjemaer for å returnere de fem første tabellene ordnet etter tabellnavnet. Selv om det ikke er så mye fornuftig å bruke et slikt spørsmål, viser dette eksemplet deg:

  • Hvordan spørre informasjonskjemadatabasen
  • Hvordan kombinere noen få kommandoer / utsagn vi har nevnt i tidligere artikler (IF… ELSE, WHILE loop, CONCAT)

Fra kodingssiden, Jeg vil understreke at vi denne gangen ikke har skrevet ut noe i en løkke, men heller opprettet en streng ved hjelp av CONCAT. Vi har også brukt IF-setningen for å teste om vi er i første omgang, og i så fall har vi ikke lagt til «,». Ellers vil vi legge til «,» i strengen.

Etter løkken har vi skrevet ut resultatstrengen, lukket og distribuert markøren.

Vi kunne oppnå dette ved hjelp av STRING_AGG-funksjonen. Denne er tilgjengelig fra og med SQL Server 2017 og tilsvarer MySQL GROUP_CONCAT-funksjonen.

SQL Server-markør – Når (ikke) skal jeg bruke dem?

Jeg prøver å gi et objektivt svar på spørsmålet – «Når du skal bruke SQL Server-markører og når ikke?» Siden ting endres i løpet av tiden og forbedringer skal gjøres, enten på markører, enten på andre objekter som «erstatter» dem, ta hensyn til datoen da denne artikkelen ble skrevet.Så la oss begynne.

Du bør ikke bruke markører:

  • Nesten alltid 🙂 Dette kan høres dumt ut, men det er sant i de fleste tilfeller. SQL Server implementerer et stort antall objekter & funksjoner som gjør akkurat det du sannsynligvis vil prøve å løse ved hjelp av markører. Før du bestemmer deg for å gå med markøren, må du være sikker på at du har undersøkt nok til å konkludere med at markøren er den eneste mulige (gode) løsningen. Samme står for sløyfer i databaser. I forrige artikkel Intro til SQL Server-sløyfer, har vi brukt sløyfer, men ikke for å sløyfe gjennom data.

Du kan bruke markører:

  • For det meste for databaseadministrasjonsoppgaver som sikkerhetskopier, integritetskontroller, gjenoppbygging av indekser
  • For engangs oppgaver når du er sikker på at mulig dårlig ytelse ikke vil påvirke systemets totale ytelse
  • Ringe til en lagret prosedyre noen ganger ved hjelp av forskjellige parametere. I så fall vil du få parametere fra markørvariabler og ringe inne i sløyfen

    Å ringe en lagret prosedyre eller et annet spørsmål inne i markøren (eller sløyfen) påvirker ytelsen mye, fordi i hvert trinn av markørsløyfe, kjører du spørringen / prosedyren fra starten. Hvis du bestemmer deg for å gjøre det, bør du være oppmerksom på mulige konsekvenser.

  • Det forrige tipset bringer oss til den siste punkten når du skal bruke markører. Hvis du er helt klar over hvordan de fungerer, og du er ganske sikker på at det ikke vil påvirke ytelsen, gå for det

SQL Server Cursor – Hvorfor folk (ikke) bruker dem ?

Det siste spørsmålet jeg vil svare på er: Hvorfor vil noen bruke en markør? Slik ser jeg det:

  • Folk som bruker dem til engangsjobber eller regelmessige handlinger der de ikke påvirker ytelsen, har unnskyldningen. En av årsakene er at slik kode er prosedyrekode, og hvis du er vant til den, er den veldig lesbar
  • På den annen side kan de som begynte å lære om databaser, og er vant til prosessuell programmering, bruk markører fordi de som nevnt er mye nærmere prosessuell programmering enn databaser. Dette er ikke en grunn til å bruke dem, fordi den eneste unnskyldningen her vil være at du rett og slett ikke vet den andre (riktige) måten hvordan du får ting gjort
  • Det viktigste med markører er at de er sakte sammenlignet med SQL-setninger, og derfor bør du unngå å bruke dem fordi de før eller siden vil føre til ytelsesproblemer (med mindre du vet nøyaktig hva du gjør og hvorfor)

I synes det er nyttig at du forstår begrepet markører fordi det er stor sjanse for at du møter dem underveis. De var populære før noen nye alternativer ble lagt til i SQL Server. Det er også en sjanse for at du fortsetter å jobbe med et system der noen før du brukte dem, og du må fortsette der de stoppet. Kanskje du må erstatte markøren (prosedyrekode) med SQL (deklarativ kode).

Konklusjon

Det er ingen bedre konklusjon på markører enn – ikke bruk dem 🙂 SQL Server implementerte mange endringer som løste problemer som var vanskelig å løse med bruk av deklarativ kode tidligere. Bruk bedre tid på å undersøke og lære noe nytt, og til slutt å produsere optimal kode. Selvfølgelig kan du bruke dem hvis du vet hvorfor du gjør det, og du er klar over mulige problemer knyttet til dem.

Innholdsfortegnelse

Lær SQL : OPPRETT DATABASE & OPPRETT TABELLoperasjoner

Lær SQL: INSERT IN TABLE

Lær SQL: Primær nøkkel

Lær SQL: Fremmed nøkkel

Lær SQL: SELECT-setning

Lær SQL: INNER JOIN vs LEFT JOIN

Lær SQL: SQL-skript

Lær SQL: Typer relasjoner

Lær SQL: Bli med i flere tabeller

Lær SQL: Aggregerte funksjoner

Lær SQL: Hvordan skrive en kompleks SELECT-spørring?

Lær SQL: INFORMASJON_SCHEMA-databasen

Lær SQL: SQL-datatyper

Lær SQL: Sett teori

Lær SQL: Brukerdefinerte funksjoner

Lær SQL: Brukerdefinerte lagrede prosedyrer

Lær SQL: SQL-visninger

Lær SQL: SQL-utløsere

Lær SQL: Øv SQL-spørsmål

Lær SQL: SQL-spørringseksempler

Lær SQL: Opprett en rapport manuelt ved hjelp av SQL-spørsmål

Lær SQL: SQL Server dato- og tidsfunksjoner

Lær SQL: Opprett SQL Server-rapporter ved hjelp av dato- og tidsfunksjoner

Lær SQL: SQL Server-pivottabeller

Lær SQL: SQL Server-eksport til Excel

Lær SQL: Introduksjon til SQL Server-sløyfer

Lær SQL: SQL Server-markører

Lær SQL: Best fremgangsmåter for SQL for sletting og oppdatering av data

Lær SQL: Navngivningskonvensjoner

Lær SQL: SQL-relaterte jobber

Lær SQL: Ikke-Equi-sammenkoblinger i SQL Server

Lær SQL: SQL Injection

  • Forfatter
  • Nylige innlegg
Emil er databaseprofesjonell med 10+ års erfaring i alt relatert til databaser. Gjennom årene jobbet han i IT- og finansbransjen og jobber nå som frilanser.
Hans tidligere og nåværende engasjement varierer fra databasedesign og koding til undervisning, rådgivning og skriving om databaser. Ikke å glemme, BI, å lage algoritmer, sjakk, filateli, 2 hunder, 2 katter, 1 kone, 1 baby …
Du finner ham på LinkedIn
Vis alle innlegg av Emil Drkusic

Siste innlegg av Emil Drkusic (se alle)
  • Lær SQL: SQL Injection – 2. november 2020
  • Lær SQL: Ikke-Equi-sammenkoblinger i SQL Server – 29. september 2020
  • Lær SQL: SQL-relaterte jobber – 1. september 2020

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *