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
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
- 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