DECLARE CURSOR (Transact-SQL) (Italiano)

  • 14/03/2017
  • 13 minuti per la lettura
    • c
    • r
    • i
    • M
    • m
    • +6

Si applica a: SQL Server (tutte le versioni supportate ) Database SQL di Azure

Definisce gli attributi di un cursore del server Transact-SQL, come il comportamento di scorrimento e la query utilizzata per creare il set di risultati su cui il cursore funziona. DECLARE CURSOR accetta sia una sintassi basata sullo standard ISO sia una sintassi che utilizza una serie di estensioni Transact-SQL.

Convenzioni della sintassi Transact-SQL

Sintassi

Nota

Per visualizzare la sintassi Transact-SQL per SQL Server 2014 e versioni precedenti, vedere la documentazione delle versioni precedenti .

Argomenti

nome_cursore
È il nome del cursore del server Transact-SQL definito. nome_cursore deve essere conforme alle regole per gli identificatori.

INSENSITIVE
Definisce un cursore che esegue una copia temporanea dei dati che devono essere utilizzati dal cursore. Tutte le richieste al cursore ricevono risposta da questa tabella temporanea in tempdb; pertanto, le modifiche apportate alle tabelle di base non si riflettono nei dati restituiti dai recuperi effettuati a questo cursore e questo cursore non consente modifiche. Quando viene utilizzata la sintassi ISO, se INSENSITIVE viene omesso, le eliminazioni e gli aggiornamenti sottoposti a commit effettuati alle tabelle sottostanti (da qualsiasi utente) si riflettono nei recuperi successivi.

SCORRI
Specifica che tutte le opzioni di recupero (FIRST, LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE) sono disponibili. Se SCROLL non è specificato in un ISO DECLARE CURSOR, NEXT è lunica opzione di recupero supportata . SCROLL non può essere specificato se è specificato anche FAST_FORWARD. Se SCROLL non è specificato, è disponibile solo lopzione di recupero NEXT e il cursore diventa FORWARD_ONLY.

select_statement
È unistruzione SELECT standard che definisce il set di risultati del cursore. Le parole chiave FOR BROWSE e INTO non sono consentite allinterno di select_statement di una dichiarazione di cursore.

SQL Server converte implicitamente il cursore su un altro tipo se le clausole in select_statement sono in conflitto con la funzionalità del tipo di cursore richiesto.

SOLO LETTURA
Impedisce gli aggiornamenti effettuati tramite questo cursore. Non è possibile fare riferimento al cursore in una clausola WHERE CURRENT OF in unistruzione UPDATE o DELETE. Questa opzione sostituisce la capacità predefinita di aggiornamento di un cursore.

nome_cursore
È il nome del cursore del server Transact-SQL definito. nome_cursore deve essere conforme alle regole per gli identificatori.

LOCALE
Specifica che lambito del cursore è locale rispetto al batch, alla procedura memorizzata o al trigger in cui è stato creato il cursore. Il nome del cursore è valido solo allinterno di questo ambito. Il cursore può essere referenziato dalle variabili del cursore locale nel batch, nella stored procedure o nel trigger o in un parametro OUTPUT della stored procedure. Un parametro OUTPUT viene utilizzato per riportare il cursore locale al batch, alla procedura memorizzata o al trigger chiamante, che può assegnare il parametro a una variabile del cursore per fare riferimento al cursore dopo la procedura memorizzata termina. Il cursore viene deallocato implicitamente quando il batch, la procedura memorizzata o il trigger termina, a meno che il cursore non sia stato ritrasmesso in un parametro OUTPUT. Se viene restituito in un parametro OUTPUT, il cursore viene deallocato quando lultima variabile che fa riferimento a esso viene deallocata o esce dallambito.

GLOBALE
Specifica che lambito del cursore è globale per la connessione. È possibile fare riferimento al nome del cursore in qualsiasi stored procedure o batch eseguito dalla connessione. Il cursore viene deallocato solo implicitamente alla disconnessione.

Nota

Se né GLOBAL o LOCAL è specificato, il valore predefinito è controllato dallimpostazione dellopzione predefinita per il database del cursore locale.

FORWARD_ONLY
Specifica che il cursore può solo spostarsi in avanti ed essere fatto scorrere dalla prima allultima riga. FETCH NEXT è lunica opzione di recupero supportata. Tutte le istruzioni di inserimento, aggiornamento ed eliminazione effettuate dallutente corrente (o salvate da altri utenti) che influiscono sulle righe nel set di risultati sono visibili quando le righe vengono recuperate.Poiché il cursore non può essere fatto scorrere allindietro, tuttavia, le modifiche apportate alle righe nel database dopo che la riga è stata recuperata non sono visibili tramite il cursore. I cursori forward-only sono dinamici per impostazione predefinita, il che significa che tutte le modifiche vengono rilevate durante lelaborazione della riga corrente. Ciò fornisce unapertura più rapida del cursore e consente al set di risultati di visualizzare gli aggiornamenti apportati alle tabelle sottostanti. Sebbene i cursori solo in avanti non supportino lo scorrimento allindietro, le applicazioni possono tornare allinizio del set di risultati chiudendo e riaprendo il cursore. Se FORWARD_ONLY viene specificato senza STATIC, KEYSET o DYNAMIC, il cursore funziona come un cursore dinamico. Quando non è specificato né FORWARD_ONLYSCROLL, FORWARD_ONLY è limpostazione predefinita, a meno che le parole chiave STATIC, KEYSET o DYNAMIC. STATIC, KEYSET e DYNAMIC i cursori per impostazione predefinita sono SCROLL. A differenza delle API di database come ODBC e ADO, FORWARD_ONLY è supportato con STATIC, KEYSET, e DYNAMIC cursori Transact-SQL.

STATICO
Specifica che il cursore visualizza sempre il set di risultati comera quando il cursore è stato aperto per la prima volta e fa una copia temporanea dei dati da utilizzare con il cursore. Tutte le richieste al cursore ricevono risposta da questa tabella temporanea in tempdb. Pertanto gli inserimenti, gli aggiornamenti e le eliminazioni effettuati alle tabelle di base non si riflettono nei dati restituiti dai recuperi effettuati su questo cursore e questo cursore non rileva le modifiche apportate allappartenenza, allordine o ai valori del set di risultati dopo che il cursore è stato aperto . I cursori statici possono rilevare i propri aggiornamenti, eliminazioni e inserimenti, sebbene non siano obbligati a farlo. Ad esempio, si supponga che un cursore statico recuperi una riga e unaltra applicazione aggiorni quella riga. Se lapplicazione recupera la riga dal cursore statico, i valori che vede rimangono invariati, nonostante le modifiche apportate dallaltra applicazione. Sono supportati tutti i tipi di scorrimento.

KEYSET
Specifica che lappartenenza e lordine delle righe nel cursore sono fissi quando il cursore viene aperto. Il set di chiavi che identifica in modo univoco le righe è incorporato in una tabella in tempdb nota come keyset. Questo cursore fornisce funzionalità tra un cursore statico e uno dinamico nella sua capacità di rilevare le modifiche. Come un cursore statico, non rileva sempre le modifiche allappartenenza e allordine del set di risultati. Come un cursore dinamico, rileva le modifiche ai valori delle righe nel set di risultati. I cursori gestiti da keyset sono controllati da un set di identificatori univoci (chiavi) noti come keyset. Le chiavi vengono create da un insieme di colonne che identificano in modo univoco le righe nel set di risultati. Il keyset è linsieme di valori chiave di tutte le righe restituite dallistruzione della query. Con i cursori gestiti da keyset, una chiave viene creata e salvata per ogni riga nel cursore e memorizzata sulla workstation client o sul server. Quando si accede a ciascuna riga, la chiave archiviata viene utilizzata per recuperare i valori dei dati correnti dallorigine dati. In un cursore gestito da keyset, lappartenenza al set di risultati viene congelata quando il keyset è completamente popolato. Successivamente, le aggiunte o gli aggiornamenti che influiscono sullappartenenza non fanno parte del set di risultati finché non viene riaperto.Le modifiche ai valori dei dati (apportate dal proprietario del keyset o da altri processi) sono visibili mentre lutente scorre il set di risultati:

  • Se una riga viene eliminata, un tentativo di recuperare la riga restituisce un @@FETCH_STATUS di -2 perché la riga eliminata appare come uno spazio vuoto nel set di risultati. La chiave per la riga esiste nel keyset, ma la riga non esiste più nel set di risultati.
  • Gli inserimenti effettuati allesterno del cursore (da altri processi) sono visibili solo se il cursore viene chiuso e riaperto. Gli inserimenti fatti dallinterno del cursore sono visibili alla fine del set di risultati.
  • Gli aggiornamenti dei valori delle chiavi dallesterno del cursore assomigliano a una cancellazione della vecchia riga seguita da un inserimento della nuova riga. La riga con i nuovi valori non è visibile e i tentativi di recuperare la riga con i vecchi valori restituiscono un @@FETCH_STATUS di -2. I nuovi valori sono visibili se laggiornamento viene eseguito tramite il cursore specificando la clausola WHERE CURRENT OF.

Nota

Se la query fa riferimento ad almeno una tabella senza un indice univoco, il cursore keyset viene convertito in un cursore statico.

DYNAMIC
Definisce un cursore che riflette tutte le modifiche ai dati apportate le righe nel suo set di risultati mentre si scorre intorno al cursore e si recupera un nuovo record, indipendentemente dal fatto che le modifiche avvengano dallinterno del cursore o da altri utenti allesterno del cursore. Pertanto tutte le istruzioni di inserimento, aggiornamento ed eliminazione effettuate da tutti gli utenti sono visibili tramite il cursore.I valori dei dati, lordine e lappartenenza alle righe possono cambiare a ogni recupero. Lopzione di recupero ABSOLUTE non è supportata con i cursori dinamici. Gli aggiornamenti effettuati allesterno del cursore non sono visibili finché non vengono salvati (a meno che il livello di isolamento della transazione del cursore non sia impostato su UNCOMMITTED). Ad esempio, supponiamo che un cursore dinamico recuperi due righe e unaltra applicazione quindi aggiorna una di queste righe ed elimina laltra. Se il cursore dinamico recupera quelle righe, non troverà la riga eliminata, ma visualizzerà i nuovi valori per la riga aggiornata.

FAST_FORWARD
Specifica un FORWARD_ONLY, READ_ONLY cursore con ottimizzazioni delle prestazioni abilitate. FAST_FORWARD non può essere specificato se è specificato anche SCROLL o FOR_UPDATE. Questo tipo di cursore non consente la modifica dei dati dallinterno del cursore.

Nota

Sia FAST_FORWARD e FORWARD_ONLY può essere utilizzato nella stessa istruzione DECLARE CURSOR.

READ_ONLY
Impedisce gli aggiornamenti effettuati tramite questo cursore. Non è possibile fare riferimento al cursore in una clausola WHERE CURRENT OF in unistruzione UPDATE o DELETE. Questa opzione sostituisce la capacità predefinita di aggiornamento di un cursore.

SCROLL_LOCKS
Specifica che è garantito che gli aggiornamenti posizionati o le eliminazioni effettuate tramite il cursore abbiano esito positivo. SQL Server blocca le righe quando vengono lette nel cursore per assicurarne la disponibilità per modifiche successive. SCROLL_LOCKS non può essere specificato se è specificato anche FAST_FORWARD o STATIC.

OPTIMISTIC
Specifica che gli aggiornamenti o le eliminazioni posizionati effettuati tramite il cursore non hanno esito positivo se la riga è stata aggiornata da quando è stata letta nel cursore. SQL Server non blocca le righe quando vengono lette nel cursore. Utilizza invece confronti dei valori della colonna timestamp o un valore checksum se la tabella non ha una colonna timestamp, per determinare se la riga è stata modificata dopo essere stata letta nel cursore. Se la riga è stata modificata, il tentativo di aggiornamento o eliminazione posizionato non riesce. OPTIMISTIC non può essere specificato se viene specificato anche FAST_FORWARD.

TYPE_WARNING
Specifica che viene inviato un messaggio di avviso al client quando il cursore viene convertito implicitamente dal tipo richiesto a un altro.

select_statement
È unistruzione SELECT standard che definisce il set di risultati del cursore. Le parole chiave COMPUTE, COMPUTE BY, FOR BROWSE e INTO non sono consentiti allinterno di select_statement di una dichiarazione di cursore.

Nota

Puoi usare un suggerimento per la query allinterno di una dichiarazione di cursore; tuttavia, se utilizzi anche la clausola FOR UPDATE OF, specifica OPTION (<query_hint>) dopo FOR UPDATE OF.

SQL Server converte implicitamente il cursore in un altro tipo se le clausole in select_statement sono in conflitto con la funzionalità del tipo di cursore richiesto. Per ulteriori informazioni, vedere Conversioni implicite del cursore.

Osservazioni

DECLARE CURSOR definisce gli attributi di un cursore del server Transact-SQL, come il suo comportamento di scorrimento e query utilizzata per costruire il set di risultati su cui opera il cursore. Listruzione OPEN popola il set di risultati e FETCH restituisce una riga dal set di risultati. Listruzione CLOSE rilascia il set di risultati corrente associato al cursore. Listruzione DEALLOCATE rilascia le risorse utilizzate dal cursore.

La prima forma dellistruzione DECLARE CURSOR utilizza lISO sintassi per la dichiarazione dei comportamenti del cursore. La seconda forma di DECLARE CURSOR utilizza estensioni Transact-SQL che consentono di definire i cursori utilizzando gli stessi tipi di cursore utilizzati nelle funzioni del cursore dellAPI del database di ODBC o ADO.

Non puoi mescolare le due forme. Se specifichi le parole chiave SCROLL o INSENSITIVE prima della parola chiave CURSOR, non puoi utilizzare nessuna parole chiave comprese tra le parole chiave CURSOR e FOR <select_statement>. Se specifichi una qualsiasi parola chiave tra le parole chiave CURSOR e FOR <select_statement>, non puoi specificare SCROLL o INSENSITIVE prima della parola chiave CURSOR.

Se un DECLARE CURSOR che utilizza la sintassi Transact-SQL non specifica READ_ONLY, OPTIMISTIC o SCROLL_LOCKS, il valore predefinito è il seguente:

  • Se SELECT non supporta gli aggiornamenti (autorizzazioni insufficienti, accesso a tabelle remote che non supportano gli aggiornamenti e così via), il cursore è READ_ONLY.

  • STATIC e i FAST_FORWARD cursori per impostazione predefinita sono READ_ONLY.

  • DYNAMIC e KEYSET cursori predefiniti su OPTIMISTIC .

I nomi dei cursori possono essere referenziati solo da altre istruzioni Transact-SQL. Non possono essere referenziati dalle funzioni API del database. Ad esempio, dopo aver dichiarato un cursore, non è possibile fare riferimento al nome del cursore dalle funzioni o dai metodi OLE DB, ODBC o ADO. Le righe del cursore non possono essere recuperate utilizzando le funzioni o i metodi di recupero delle API; le righe possono essere recuperate solo dalle istruzioni Transact-SQL FETCH.

Dopo che un cursore è stato dichiarato, queste procedure memorizzate di sistema possono essere utilizzate per determinare le caratteristiche del cursore.

Procedure memorizzate di sistema Descrizione
sp_cursor_list Restituisce un elenco di cursori attualmente visibili sulla connessione e i loro attributi.
sp_describe_cursor Descrive gli attributi di un cursore, ad esempio se si tratta di un cursore solo in avanti o di scorrimento.
sp_describe_cursor_columns Descrive gli attributi delle colonne nel set di risultati del cursore.
sp_describe_cursor_tables Descrive le tabelle di base a cui si accede dal cursore.

Le variabili possono essere utilizzate come parte dellistruzione select_statement che dichiara un cursore. I valori delle variabili del cursore non cambiano dopo la dichiarazione di un cursore.

Autorizzazioni

Le autorizzazioni di DECLARE CURSOR sono predefinite per qualsiasi utente con SELECT autorizzazioni per visualizzazioni, tabelle e colonne utilizzate nel cursore.

Limitazioni e restrizioni

Non è possibile utilizzare cursori o trigger su una tabella con un indice columnstore cluster. Questa restrizione non si applica agli indici columnstore non cluster; puoi utilizzare cursori e trigger su una tabella con un indice columnstore non cluster.

Esempi

A. Uso del cursore e della sintassi semplici

Il set di risultati generato allapertura di questo cursore include tutte le righe e tutte le colonne nella tabella. Questo cursore può essere aggiornato e tutti gli aggiornamenti e le eliminazioni sono rappresentati nei recuperi effettuati su questo cursore. FETCH NEXT è lunico recupero disponibile perché lopzione SCROLL non è stata specificata.

B. Utilizzo di cursori nidificati per produrre output di report

Il seguente esempio mostra come i cursori possono essere nidificati per produrre report complessi. Il cursore interno viene dichiarato per ogni fornitore.

Vedi anche

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *