DECLARE CURSOR (Transact-SQL) (Română)

  • 14.03.2017
  • 13 minute de citit
    • c
    • r
    • i
    • M
    • m
    • +6

Se aplică la: SQL Server (toate versiunile acceptate ) Azure SQL Database

Definește atributele unui cursor de server Transact-SQL, cum ar fi comportamentul său de derulare și interogarea utilizată pentru a construi setul de rezultate pe care cursorul funcționează. DECLARE CURSOR acceptă atât o sintaxă bazată pe standardul ISO, cât și o sintaxă utilizând un set de extensii Transact-SQL.

Convenții de sintaxă Transact-SQL

Sintaxă

Notă

Pentru a vizualiza sintaxa Transact-SQL pentru SQL Server 2014 și versiuni anterioare, consultați documentația versiunilor anterioare .

Argumente

cursor_name
Este definit cursorul serverului Transact-SQL. cursor_name trebuie să respecte regulile pentru identificatori.

INSENSIBIL
Definește un cursor care face o copie temporară a datelor pentru a fi utilizate de cursor. Toate cererile către cursor sunt răspunsuri din acest tabel temporar în tempdb; prin urmare, modificările aduse tabelelor de bază nu sunt reflectate în datele returnate de preluările făcute acestui cursor și acest cursor nu permite modificări. Când este utilizată sintaxa ISO, dacă INSENSITIVE este omis, ștergerile confirmate și actualizările făcute la tabelele de bază (de către orice utilizator) sunt reflectate în preluările ulterioare.

SCROLL
Specifică toate opțiunile de preluare (FIRST, LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE) sunt disponibile. Dacă SCROLL nu este specificat într-un ISO DECLARE CURSOR, NEXT este singura opțiune de preluare acceptată . SCROLL nu poate fi specificat dacă se specifică și FAST_FORWARD. Dacă nu este specificat SCROLL, atunci este disponibilă doar opțiunea de preluare NEXT, iar cursorul devine FORWARD_ONLY.

select_statement
Este o declarație standard SELECT care definește setul de rezultate al cursorului. Cuvintele cheie FOR BROWSE și INTO nu sunt permise în select_statement al unei declarații de cursor.

SQL Server convertește implicit cursorul la un alt tip dacă clauzele din select_statement intră în conflict cu funcționalitatea tipului de cursor solicitat.

CITIȚI NUMAI
Previne actualizările făcute prin intermediul acestui cursor. Cursorul nu poate fi menționat într-o clauză WHERE CURRENT OF dintr-o declarație UPDATE sau DELETE. Această opțiune suprascrie capacitatea implicită a unui cursor de actualizat.

cursor_name
Este numele cursorului serverului Transact-SQL definit. cursor_name trebuie să respecte regulile pentru identificatori.

LOCAL
Specifică faptul că scopul cursorului este local pentru lotul, procedura stocată sau declanșatorul în care a fost creat cursorul. Numele cursorului este valabil numai în acest domeniu. Cursorul poate fi menționat de variabilele locale ale cursorului în lot, procedură stocată sau declanșator sau un parametru OUTPUT de procedură stocată. Un parametru OUTPUT este utilizat pentru a transmite cursorul local înapoi la lotul apelant, la procedura stocată sau la declanșator, care poate atribui parametrul unei variabile a cursorului pentru a face referire la cursor după procedura stocată se termină. Cursorul este implicit repartizat atunci când lotul, procedura stocată sau declanșatorul se termină, cu excepția cazului în care cursorul a fost trecut înapoi într-un parametru OUTPUT. Dacă este trecut înapoi într-un parametru OUTPUT, cursorul este repartizat atunci când ultima variabilă care face referire la acesta este repartizată sau iese din sfera de aplicare.

GLOBAL
Specifică faptul că scopul cursorului este global la conexiune. Numele cursorului poate fi menționat în orice procedură stocată sau lot executat de conexiune. Cursorul este alocat implicit doar la deconectare.

Notă

Dacă nici GLOBAL sau LOCAL este specificat, valoarea implicită este controlată de setarea opțiunii implicite la baza de date a cursorului local.

FORWARD_ONLY
Specifică faptul că cursorul se poate deplasa înainte și poate fi derulat de la primul până la ultimul rând. FETCH NEXT este singura opțiune de preluare acceptată. Toate instrucțiunile de inserare, actualizare și ștergere făcute de utilizatorul curent (sau angajate de alți utilizatori) care afectează rândurile din setul de rezultate sunt vizibile pe măsură ce rândurile sunt preluate.Deoarece cursorul nu poate fi derulat înapoi, totuși, modificările aduse rândurilor din baza de date după preluarea rândului nu sunt vizibile prin intermediul cursorului. Cursorele numai înainte sunt dinamice în mod implicit, ceea ce înseamnă că toate modificările sunt detectate pe măsură ce rândul curent este procesat. Aceasta oferă o deschidere mai rapidă a cursorului și permite setului de rezultate să afișeze actualizările făcute la tabelele subiacente. În timp ce cursorii numai înainte nu acceptă derularea înapoi, aplicațiile pot reveni la începutul setului de rezultate închizând și redeschizând cursorul. Dacă FORWARD_ONLY este specificat fără STATIC, KEYSET sau DYNAMIC cuvinte cheie, cursorul funcționează ca un cursor dinamic. Când nici FORWARD_ONLY și nici SCROLL nu sunt specificate, FORWARD_ONLY este implicit, cu excepția cazului în care cuvintele cheie STATIC, KEYSET sau DYNAMIC. STATIC, KEYSET și DYNAMIC cursorii sunt în mod implicit SCROLL. Spre deosebire de API-urile bazelor de date precum ODBC și ADO, FORWARD_ONLY este acceptat cu STATIC, KEYSET, și DYNAMIC Cursorii Transact-SQL.

STATIC
Specifică faptul că cursorul afișează întotdeauna setul de rezultate așa cum a fost când a fost deschis cursorul și face o copie temporară a datelor care urmează să fie utilizate de cursor. Toate cererile către cursor sunt răspunsuri din acest tabel temporar în tempdb. Prin urmare, inserțiile, actualizările și ștergerile făcute în tabelele de bază nu sunt reflectate în datele returnate de preluările făcute acestui cursor, iar acest cursor nu detectează modificările aduse membrilor, ordinii sau valorilor rezultatului setat după deschiderea cursorului . Cursorii statici își pot detecta propriile actualizări, ștergeri și inserții, deși nu sunt obligați să facă acest lucru. De exemplu, să presupunem că un cursor static preluează un rând, iar o altă aplicație actualizează acel rând. Dacă aplicația reintroduce rândul de la cursorul static, valorile pe care le vede sunt neschimbate, în ciuda modificărilor făcute de cealaltă aplicație. Sunt acceptate toate tipurile de derulare.

KEYSET
Specifică faptul că apartenența și ordinea rândurilor din cursor sunt fixate când cursorul este deschis. Setul de taste care identifică în mod unic rândurile este încorporat într-un tabel în tempdb cunoscut sub numele de set de taste. Acest cursor oferă funcționalitate între un cursor static și unul dinamic în capacitatea sa de a detecta modificările. La fel ca un cursor static, nu detectează întotdeauna modificările aderării și ordinii setului de rezultate. La fel ca un cursor dinamic, acesta detectează modificările valorilor rândurilor din setul de rezultate. Cursorii cu cheie sunt controlați de un set de identificatori unici (taste) cunoscut sub numele de set de taste. Cheile sunt construite dintr-un set de coloane care identifică în mod unic rândurile din setul de rezultate. Setul de taste este setul de valori cheie din toate rândurile returnate de instrucțiunea de interogare. Cu ajutorul cursoarelor bazate pe setul de taste, o tastă este construită și salvată pentru fiecare rând din cursor și stocată fie pe stația de lucru client, fie pe server. Când accesați fiecare rând, cheia stocată este utilizată pentru a prelua valorile curente ale datelor din sursa de date. Într-un cursor bazat pe setul de taste, apartenența la setul de rezultate este înghețată atunci când setul de taste este complet completat. Ulterior, adăugirile sau actualizările care afectează calitatea de membru nu fac parte din setul de rezultate până când nu este redeschis. Modificările valorilor datelor (făcute fie de proprietarul setului de chei, fie de alte procese) sunt vizibile pe măsură ce utilizatorul parcurge setul de rezultate:

  • Dacă un rând este șters, o încercare de a prelua rândul returnează un @@FETCH_STATUS de -2, deoarece rândul șters apare ca un spațiu în setul de rezultate. Cheia pentru rând există în setul de taste, dar rândul nu mai există în setul de rezultate.
  • Inserturile realizate în afara cursorului (prin alte procese) sunt vizibile numai dacă cursorul este închis și redeschis. Inserturile realizate din interiorul cursorului sunt vizibile la sfârșitul setului de rezultate.
  • Actualizările valorilor cheie din afara cursorului seamănă cu o ștergere a vechiului rând urmat de o inserare a noului rând. Rândul cu noile valori nu este vizibil și încercările de a prelua rândul cu valorile vechi returnează un @@FETCH_STATUS de -2. Noile valori sunt vizibile dacă actualizarea se face prin intermediul cursorului prin specificarea clauzei WHERE CURRENT OF.

Notă

Dacă interogarea face referire la cel puțin un tabel fără un index unic, cursorul setului de taste este convertit într-un cursor static.

DINAMIC
Definește un cursor care reflectă toate modificările de date efectuate la rândurile din setul său de rezultate în timp ce derulați cursorul și preluați o nouă înregistrare, indiferent dacă modificările au loc din interiorul cursorului sau de către alți utilizatori din afara cursorului. Prin urmare, toate instrucțiunile de inserare, actualizare și ștergere făcute de toți utilizatorii sunt vizibile prin intermediul cursorului.Valorile datelor, ordinea și apartenența la rânduri se pot modifica la fiecare preluare. Opțiunea de preluare ABSOLUTE nu este acceptată cu cursorii dinamici. Actualizările făcute în afara cursorului nu sunt vizibile până când nu sunt angajate (cu excepția cazului în care nivelul de izolare a tranzacției cursorului este setat la UNCOMMITTED). actualizează unul dintre aceste rânduri și îl șterge pe celălalt. Dacă cursorul dinamic preluează acele rânduri, acesta nu va găsi rândul șters, dar va afișa noile valori pentru rândul actualizat.

FAST_FORWARD
Specifică un FORWARD_ONLY, READ_ONLY cursor cu optimizări de performanță activate. FAST_FORWARD nu poate fi specificat dacă se specifică și SCROLL sau FOR_UPDATE. Acest tip de cursor nu permite modificarea datelor din interiorul cursorului.

Notă

Atât FAST_FORWARD, cât și poate fi utilizat în aceeași instrucțiune DECLARE CURSOR.

READ_ONLY
Previne actualizările făcute prin intermediul acestui cursor. Cursorul nu poate fi menționat într-o clauză WHERE CURRENT OF dintr-o declarație UPDATE sau DELETE. Această opțiune suprascrie capacitatea implicită a unui cursor care urmează să fie actualizat.

SCROLL_LOCKS
Specifică faptul că actualizările poziționate sau ștergerile efectuate prin intermediul cursorului sunt garantate pentru a avea succes. SQL Server blochează rândurile pe măsură ce sunt citite în cursor pentru a le asigura disponibilitatea pentru modificări ulterioare. SCROLL_LOCKS nu poate fi specificat dacă se specifică și FAST_FORWARD sau STATIC.

OPTIMISTIC
Specifică faptul că actualizările sau ștergerile poziționate efectuate prin intermediul cursorului nu reușesc dacă rândul a fost actualizat de când a fost citit în cursor. SQL Server nu blochează rândurile pe măsură ce sunt citite în cursor. În schimb, folosește comparații ale valorilor coloanei de marcă de timp sau o valoare a sumei de control dacă tabelul nu are coloană de marcă de timp, pentru a determina dacă rândul a fost modificat după ce a fost citit în cursor. Dacă rândul a fost modificat, încercarea de actualizare sau ștergere poziționată eșuează. OPTIMISTIC nu poate fi specificat dacă este specificat și FAST_FORWARD.

TYPE_WARNING
Specifică trimiterea unui mesaj de avertizare către client când cursorul este implicit convertit de la tipul solicitat la altul.

select_statement
Este o instrucțiune SELECT standard care definește setul de rezultate al cursorului. Cuvintele cheie COMPUTE, COMPUTE BY, FOR BROWSE și INTO nu sunt permise în select_statement al unei declarații de cursor.

Notă

Puteți utiliza un indiciu de interogare într-o declarație de cursor; totuși, dacă utilizați și clauza FOR UPDATE OF, specificați OPTION (<query_hint>) după FOR UPDATE OF.

SQL Server implicit convertește cursorul la un alt tip dacă clauzele din select_statement intră în conflict cu funcționalitatea tipului de cursor solicitat. Pentru mai multe informații, consultați Conversii implicite ale cursorilor.

Observații

DECLARE CURSOR definește atributele unui cursor server Transact-SQL, cum ar fi comportamentul de derulare și interogarea utilizată pentru a construi setul de rezultate pe care funcționează cursorul. Instrucțiunea OPEN completează setul de rezultate și FETCH returnează un rând din setul de rezultate. Instrucțiunea CLOSE eliberează setul de rezultate curent asociat cu cursorul. Instrucțiunea DEALLOCATE eliberează resursele utilizate de cursor.

Prima formă a instrucțiunii DECLARE CURSOR utilizează ISO sintaxă pentru declararea comportamentelor cursorului. A doua formă de DECLARE CURSOR folosește extensii Transact-SQL care vă permit să definiți cursoare utilizând aceleași tipuri de cursori utilizate în funcțiile de cursor API ale bazei de date ODBC sau ADO.

Nu puteți amesteca cele două forme. Dacă specificați cuvintele cheie SCROLL sau INSENSITIVE înainte de cuvântul cheie CURSOR, nu puteți utiliza cuvinte cheie între CURSOR și FOR <select_statement> cuvinte cheie. Dacă specificați cuvinte cheie între CURSOR și FOR <select_statement> cuvinte cheie, nu puteți specifica SCROLL sau INSENSITIVE înainte de cuvântul cheie CURSOR.

Dacă o DECLARE CURSOR care utilizează sintaxa Transact-SQL nu specifică READ_ONLY, OPTIMISTIC sau SCROLL_LOCKS, valoarea implicită este următoarea:

  • Dacă SELECT nu acceptă actualizări (permisiuni insuficiente, accesarea tabelelor la distanță care nu acceptă actualizări și așa mai departe), cursorul este READ_ONLY.

  • STATIC și FAST_FORWARD cursorii sunt în mod implicit READ_ONLY.

  • DYNAMIC și KEYSET cursorii sunt în mod implicit OPTIMISTIC .

Numele cursorilor pot fi menționate numai de alte instrucțiuni Transact-SQL. Ele nu pot fi menționate de funcțiile API ale bazei de date. De exemplu, după declararea unui cursor, numele cursorului nu poate fi menționat din funcțiile sau metodele OLE DB, ODBC sau ADO. Rândurile cursorului nu pot fi preluate folosind funcțiile de preluare sau metodele API-urilor; rândurile pot fi preluate numai prin instrucțiuni Transact-SQL FETCH.

După ce a fost declarat un cursor, aceste proceduri stocate în sistem pot fi utilizate pentru a determina caracteristicile cursorului.

Proceduri stocate în sistem Descriere
sp_cursor_list Returnează o listă de cursori vizibili în prezent pe conexiune și atributele acestora.
sp_describe_cursor Descrie atributele unui cursor, cum ar fi dacă este doar un cursor înainte sau un cursor cu defilare.
sp_describe_cursor_columns Descrie atributele coloanelor din setul de rezultate ale cursorului.
sp_describe_cursor_tables Descrie tabelele de bază accesate de cursor.

Variabilele pot fi utilizate ca parte a select_statement care declară un cursor. Valorile variabilelor cursorului nu se modifică după declararea unui cursor.

Permisiuni

Permisiuni DECLARE CURSOR implicite pentru orice utilizator care are SELECT permisiuni pentru vizualizări, tabele și coloane utilizate în cursor.

Limitări și restricții

Nu puteți utiliza cursori sau declanșatoare pe o masă cu un index de depozit de coloane grupat. Această restricție nu se aplică indecșilor de depozite de coloane non-grupate; puteți utiliza cursorele și declanșatoarele pe un tabel cu un index de depozit de coloane noncluster.

Exemple

A. Folosind cursorul și sintaxa simple

Setul de rezultate generat la deschiderea acestui cursor include toate rândurile și toate coloanele din tabel. Acest cursor poate fi actualizat și toate actualizările și ștergerile sunt reprezentate în preluările făcute împotriva acestui cursor. FETCH NEXT este singura preluare disponibilă, deoarece opțiunea SCROLL nu a fost specificată.

B. Utilizarea cursorilor imbricate pentru a produce ieșirea raportului

Următorul exemplu arată cum pot fi imbricate cursorii pentru a produce rapoarte complexe. Cursorul interior este declarat pentru fiecare furnizor.

Consultați și

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *