SQLShack (Română)
Cursorii SQL Server sunt un subiect comun pe Internet . Veți găsi opinii diferite când să le folosiți și când să nu le faceți. Astăzi, vom vorbi și despre ele și vom răspunde la întrebarea când (nu) să le folosim.
Modelul de date și ideea generală
În articolul precedent, Introducere în SQL Bucle de server, am vorbit despre bucle de SQL Server, dar nu am folosit date din baza de date. A fost ciudat, dar acum ar trebui să devină mult mai clar. Astăzi, în timp ce explicăm cursorii, vom folosi datele din baza de date pentru a arăta când (nu) să folosim cursorii. Modelul de date pe care îl vom folosi este același pe care îl folosim în toată această serie.
SQL Server acceptă 3 diferite implementări ale cursorelor – cursoare Transact-SQL, cursoare API și cursoare Client. În acest articol, ne vom concentra asupra cursoarelor Transact-SQL. Le veți recunoaște cu ușurință deoarece se bazează pe sintaxa DECLARE CURSOR.
Cursorul SQL Server – Introducere
Înainte de a trece la cod și exemple, ar trebui să explicăm ce cursori SQL Server are.
Cursorul SQL Server este logica T-SQL, care ne permite să parcurgem rezultatul interogării aferent. Acest lucru ne permite să acționăm secvențial – de exemplu, să efectuăm o actualizare pe un singur rând.
Uneori, acest lucru (poate) pare util, dar atunci când lucrați cu baze de date, nu ar trebui să utilizați modele de programare procedurală ci mai degrabă rămâneți la programarea declarativă. Unul dintre principalele motive este că SGBD-urile sunt deja optimizate pentru a efectua acțiuni pe seturi de date și, prin urmare, nu ar trebui să fiți cel care încearcă să fie „mai inteligent decât sistemul”.
Totuși, este bine să știți cum funcționează. Dacă nu altceva, poate îi veți întâlni în codul pe care îl moșteniți și va trebui să rescrieți logica. Și înainte de a face ceva, ar trebui să înțelegeți cum funcționează.
Deci, în cazul în care aveți nevoie de cursoare, acesta este ceea ce ar trebui să știți despre ele:
- Cursorii folosesc variabile pentru a stoca valorile returnate în fiecare parte a buclei. Prin urmare, va trebui să DECLARAȚI toate variabilele de care aveți nevoie
- Următorul lucru de făcut este să DECLARAȚI … CURSOR PENTRU SELECT interogare, unde veți declara un cursor și de asemenea defini interogarea legată de (popularea) acel cursor
- Veți DESCHIDE cursorul și FETCH NEXT din cursor
- În bucla WHILE veți testa variabila @@ FETCH_STATUS (WHILE @@ FETCH_STATUS = 0). Dacă condiția este valabilă, Vom intra în bucla ÎNCEPE … Blocați END și efectuați instrucțiuni în interiorul acelui bloc
- După ce ați parcurs întregul set de rezultate, veți ieși din buclă. Ar trebui să ÎNCHIDEȚI cursorul și să îl DEALocaȚI. Deallocarea este importantă deoarece aceasta va șterge definiția cursorului și va elibera memoria utilizată
Cursorul SQL Server – Exemple
Să aruncăm acum o privire la două exemple de cursor. Deși sunt destul de simple, ele explică cum funcționează cursorele.
În primul exemplu, dorim să obținem toate ID-urile și numele orașelor, împreună cu numele de țară aferente. Vom folosi comanda PRINT pentru a imprima combinații în fiecare trecere a buclei.
Utilizând cursorul SQL Server și în timp ce bucla a returnat exact ceea ce ne-am așteptat – ID-uri și nume ale tuturor orașelor și țărilor înrudite, le avem în baza de date.
Cel mai important lucru de menționat aici este că am putea returna pur și simplu acest set de rezultate folosind interogarea SQL originală stocată în partea DECLARE a cursorului, deci nu a fost nevoie de un cursor.
Vom merge cu încă un exemplu. De data aceasta vom interoga baza de date a schemei de informații pentru a returna primele 5 tabele ordonate după numele tabelului. Deși nu are prea mult sens să folosiți o astfel de interogare, acest exemplu vă arată:
- Cum să interogați baza de date a schemei de informații
- Cum să combinați câteva comenzi / instrucțiuni Am menționat în articolele anterioare (IF… ELSE, WHILE loop, CONCAT)
Din partea codificării, Aș dori să subliniez că de data aceasta nu am imprimat nimic într-o buclă, ci am creat mai degrabă un șir folosind CONCAT. De asemenea, am folosit instrucțiunea IF pentru a testa dacă suntem în prima trecere și, dacă da, nu am adăugat „,”. În caz contrar, am adăuga „,” la șir.
După buclă, am imprimat șirul de rezultate, am închis și am repartizat cursorul.
Am putea realiza acest lucru folosind funcția STRING_AGG. Acesta este disponibil începând cu SQL Server 2017 și este echivalentul funcției MySQL GROUP_CONCAT.
Cursorul SQL Server – Când (Nu) să le folosesc?
Voi încerca să dați un răspuns obiectiv la întrebarea – „Când ar trebui să utilizați cursorii SQL Server și când nu”? Deoarece lucrurile se schimbă în timp și se vor face îmbunătățiri, fie pe cursoare, fie pe alte obiecte care le „înlocuiesc”, luați în considerare data la care a fost scris acest articol.Deci, să începem.
Nu ar trebui să utilizați cursorele:
- Aproape întotdeauna 🙂 Acest lucru ar putea părea prost, dar acest lucru este adevărat în majoritatea cazurilor. SQL Server implementează un număr mare de obiecte & funcții care fac exact ceea ce probabil ați încerca să rezolvați folosind cursorele. Înainte de a decide să mergeți cu cursorul, asigurați-vă că ați investigat suficient pentru a concluziona că cursorul este singura soluție posibilă (bună). Același lucru înseamnă bucle în baze de date. În articolul precedent, Introducere în buclele SQL Server, am folosit bucle, dar nu pentru a parcurge datele.
Puteți utiliza cursorele:
- În principal pentru sarcini de administrare a bazelor de date, cum ar fi copii de siguranță, verificări de integritate, reconstituirea indexurilor
- Pentru o singură dată sarcini atunci când sunteți sigur că o performanță slabă posibilă nu va afecta performanța generală a sistemului. În acest caz, veți obține parametri din variabilele cursorului și efectuați apeluri în interiorul buclei
Apelarea unei proceduri stocate sau a unei alte interogări în interiorul cursorului (sau buclei) are un impact semnificativ asupra performanței, deoarece, în fiecare etapă a bucla cursorului, veți rula interogarea / procedura de la început. Dacă decideți să faceți acest lucru, ar trebui să fiți conștienți de posibilele consecințe.
- Sugestia anterioară ne aduce la ultimul glonț atunci când ar trebui să utilizați cursorele. Dacă sunteți complet conștienți de modul în care funcționează și sunteți sigur că nu va afecta performanța, mergeți la el
Cursorul SQL Server – De ce oamenii (nu) le folosesc ?
Ultima întrebare la care aș dori să răspund este: De ce ar folosi cineva un cursor? Acesta este modul în care îl văd:
- Persoanele care le folosesc pentru sarcini unice sau acțiuni regulate în care nu vor avea impact asupra performanței au scuza. Unul dintre motive este că un astfel de cod este un cod procedural și, dacă sunteți obișnuit cu el, este foarte ușor de citit
- Pe de altă parte, cei care au început să învețe despre baze de date și sunt obișnuiți cu programarea procedurală ar putea folosiți cursoare deoarece, așa cum am menționat, sunt mult mai aproape de programarea procedurală decât de bazele de date. Acesta nu este un motiv pentru a le folosi, deoarece singura scuză aici ar fi că pur și simplu nu știți celălalt mod (corect) cum să faceți lucrurile
- Cel mai important lucru despre cursoare este că acestea sunt lente în comparație cu instrucțiunile SQL și, prin urmare, ar trebui să evitați utilizarea acestora, deoarece acestea vor duce mai devreme sau mai târziu la probleme de performanță (cu excepția cazului în care știți exact ce faceți și de ce)
vi se pare util să înțelegeți conceptul de cursoare, deoarece există șanse mari să le întâlniți pe parcurs. Au fost populare înainte ca unele opțiuni noi să fie adăugate la SQL Server De asemenea, există șansa să continuați să lucrați la un sistem în care cineva înainte de a le utiliza și va trebui să continuați acolo unde s-au oprit. Poate că va trebui să înlocuiți cursorul (codul de procedură) cu SQL (codul declarativ).
Concluzie
Nu există o concluzie mai bună asupra cursorilor decât – nu le utilizați 🙂 SQL Server a implementat o mulțime de modificări care rezolvă probleme care erau greu de rezolvat folosind codul declarativ anterior. Mai bine petreceți ceva timp investigând și învățând ceva nou și, în cele din urmă, producând un cod optim. Desigur, le puteți folosi dacă știți de ce faceți acest lucru și sunteți conștient de posibilele probleme legate de acestea.
Cuprins
Aflați SQL : CREATE DATABASE & CREATE TABLE Operations
Learn SQL: INSERT INTO TABLE
Learn SQL: Primary Key
Learn SQL: Foreign Key
Learn SQL: SELECT statement
Learn SQL: INNER JOIN vs LEFT JOIN
Learn SQL: SQL Scripts
Learn SQL: Tipuri de relații
Learn SQL: Alăturați mai multor tabele
Learn SQL: Aggregate Functions
Learn SQL: How to Write a Complex SELECT Query?
Learn SQL: Baza de date INFORMATION_SCHEMA
Learn SQL: Tipuri de date SQL
Learn SQL: Set Theory
Learn SQL: Funcții definite de utilizator
Learn SQL: Proceduri stocate definite de utilizator
Learn SQL: SQL Views
Learn SQL: SQL Triggers
Learn SQL: Practice SQL Queries
Learn SQL: SQL Query examples
Aflați SQL: creați manual un raport folosind interogări SQL
Aflați SQL: funcții de dată și oră SQL Server
Aflați SQL: creați rapoarte SQL Server utilizarea funcțiilor de dată și oră
Aflați SQL: Tabelele pivot SQL Server
Aflați SQL: Exportați SQL Server în Excel
Aflați SQL: Introducere în buclele SQL Server
Aflați SQL: Cursori SQL Server
Aflați SQL: Cele mai bune practici SQL pentru ștergerea și actualizarea datelor
Aflați SQL: Convenții de numire
Aflați SQL: joburi legate de SQL
Aflați SQL: Îmbinări non-Equi în SQL Server
Aflați SQL: SQL Injection
- Autor
- Postări recente
Angajamentele sale din trecut și prezent variază de la proiectarea și codificarea bazelor de date până la predare, consultanță și scriere despre baze de date. De asemenea, să nu uităm, BI, creând algoritmi, șah, filatelie, 2 câini, 2 pisici, 1 soție, 1 bebeluș …
Îl poți găsi pe LinkedIn
Vezi toate mesajele lui Emil Drkusic
- Learn SQL: SQL Injection – 2 noiembrie 2020
- Learn SQL: Non-Equi Joins in SQL Server – 29 septembrie 2020
- Learn SQL: Locuri de muncă legate de SQL – 1 septembrie 2020