Informazioni sui tipi di cursore

Scaricare il driver JDBC

Nei database relazionali le operazioni vengono eseguite su set di righe completi. Il set di righe restituito da un'istruzione SELECT include tutte le righe che soddisfano le condizioni specificate nella clausola WHERE dell'istruzione. Il set di righe completo restituito dall'istruzione è noto come set di risultati. Le applicazioni non sono sempre in grado di gestire in modo efficiente l'intero set di risultati come singola unità. Necessitano quindi di un meccanismo per l'elaborazione di una riga singola o di un blocco di righe di dimensioni ridotte. I cursori sono un'estensione dei set di risultati che implementano appunto tale meccanismo.

I cursori estendono l'elaborazione dei set di risultati nei modi seguenti:

  • Consentono il posizionamento su righe specifiche del set di risultati.
  • Recuperano una riga o un blocco di righe dalla posizione corrente del set di risultati.
  • Supportano le modifiche ai dati della riga in corrispondenza della posizione corrente nel set di risultati.
  • Supportano livelli diversi di visibilità per le modifiche apportate da altri utenti ai dati del database inclusi nel set di risultati.

Nota

Per una descrizione completa dei tipi di cursore di SQL Server, vedere Tipo di cursori.

La specifica JDBC fornisce supporto per cursori forward-only e scorrevoli sensibili o non sensibili alle modifiche apportate da altri processi e che possono essere di sola lettura o aggiornabili. Questa funzionalità viene fornita dalla classe SQLServerResultSet di Microsoft JDBC Driver per SQL Server.

Osservazioni:

Il driver JDBC supporta i tipi di cursori e set di risultati seguenti insieme alle opzioni di comportamento specificate.

Tipo di set di risultati (cursore) Tipo di cursore di SQL Server Caratteristiche Metodo select Memorizzazione delle risposte nel buffer
TYPE_FORWARD_ONLY (CONCUR_READ_ONLY) N/D Forward-only, di sola lettura dirette full

L'applicazione deve eseguire una singola iterazione (in avanti) nel set di risultati. Si tratta del comportamento predefinito, analogo a quello di un cursore TYPE_SS_DIRECT_FORWARD_ONLY. Tramite il driver viene letto l'intero set di risultati dal server caricandolo in memoria durante l'esecuzione dell'istruzione.

Tipo di set di risultati (cursore) Tipo di cursore di SQL Server Caratteristiche Metodo select Memorizzazione delle risposte nel buffer
TYPE_FORWARD_ONLY (CONCUR_READ_ONLY) N/D Forward-only, di sola lettura dirette adaptive

L'applicazione deve eseguire una singola iterazione (in avanti) nel set di risultati. Il comportamento corrisponde a quello di un cursore TYPE_SS_DIRECT_FORWARD_ONLY. Il driver legge le righe dal server quando vengono richieste dall'applicazione e riduce al minimo l'utilizzo della memoria sul lato client.

Tipo di set di risultati (cursore) Tipo di cursore di SQL Server Caratteristiche Metodo select Memorizzazione delle risposte nel buffer
TYPE_FORWARD_ONLY (CONCUR_READ_ONLY) Fast forward Forward-only, di sola lettura cursor N/D

L'applicazione deve eseguire una singola iterazione (in avanti) nel set di risultati utilizzando un cursore server. Il comportamento è analogo a quello di un cursore TYPE_SS_SERVER_CURSOR_FORWARD_ONLY.

Le righe vengono recuperate dal server in blocchi specificati dalla dimensione di recupero.

Tipo di set di risultati (cursore) Tipo di cursore di SQL Server Caratteristiche Metodo select Memorizzazione delle risposte nel buffer
TYPE_FORWARD_ONLY (CONCUR_UPDATABLE) Dinamico (forward-only) Forward-only, aggiornabile N/D N/D

L'applicazione deve eseguire una singola iterazione (in avanti) nel set di risultati per aggiornare una o più righe.

Le righe vengono recuperate dal server in blocchi specificati dalla dimensione di recupero.

Per impostazione predefinita, la dimensione di recupero viene fissata quando l'applicazione chiama il metodo setFetchSize dell'oggetto SQLServerResultSet.

Nota

Il driver JDBC fornisce una funzionalità di buffering adattivo che consente di recuperare i risultati dell'esecuzione delle istruzioni da SQL Server quando sono necessari per l'applicazione invece che tutti contemporaneamente. Se ad esempio l'applicazione deve recuperare una quantità di dati eccessiva per essere caricata completamente in memoria, il buffer adattivo consente all'applicazione client di recuperare tali dati sotto forma di flusso. Il comportamento predefinito del driver è "adaptive". Per ottenere il buffer adattivo per i set di risultati aggiornabili forward-only, l'applicazione deve tuttavia chiamare in modo esplicito il metodo setResponseBuffering dell'oggetto SQLServerStatement offrendo un valore Stringa "adaptive". Per un esempio di codice, vedere Esempio di aggiornamento di dati di grandi dimensioni.

Tipo di set di risultati (cursore) Tipo di cursore di SQL Server Caratteristiche Metodo select Memorizzazione delle risposte nel buffer
TYPE_SCROLL_INSENSITIVE Statico Scorrevole, non aggiornabile

Gli aggiornamenti, gli inserimenti e le eliminazioni di righe eseguiti esternamente non sono visibili.
N/D N/D

L'applicazione richiede uno snapshot del database. Il set di risultati non è aggiornabile. È supportato solo CONCUR_READ_ONLY. Tutti gli altri tipi di concorrenza generano un'eccezione, se utilizzati con questo tipo di cursore.

Le righe vengono recuperate dal server in blocchi specificati dalla dimensione di recupero.

Tipo di set di risultati (cursore) Tipo di cursore di SQL Server Caratteristiche Metodo select Memorizzazione delle risposte nel buffer
TYPE_SCROLL_SENSITIVE (CONCUR_READ_ONLY) Keyset Scorrevole, sola lettura. Gli aggiornamenti di righe eseguiti esternamente sono visibili e le eliminazioni vengono visualizzate come dati mancanti.

Gli inserimenti di righe eseguiti esternamente non sono visibili.
N/D N/D

Nell'applicazione devono essere visualizzati i dati modificati solo per le righe esistenti.

Le righe vengono recuperate dal server in blocchi specificati dalla dimensione di recupero.

Tipo di set di risultati (cursore) Tipo di cursore di SQL Server Caratteristiche Metodo select Memorizzazione delle risposte nel buffer
TYPE_SCROLL_SENSITIVE (CONCUR_UPDATABLE, CONCUR_SS_SCROLL_LOCKS, CONCUR_SS_OPTIMISTIC_CC, CONCUR_SS_OPTIMISTIC_CCVAL) Keyset Scorrevole, aggiornabile

Gli aggiornamenti di righe eseguiti internamente ed esternamente sono visibili e le eliminazioni vengono visualizzate come dati mancanti, mentre gli inserimenti non sono visibili.
N/D N/D

L'applicazione può modificare i dati nelle righe esistenti tramite l'oggetto ResultSet. L'applicazione deve inoltre essere in grado di visualizzare le modifiche apportate alle righe da altri esternamente all'oggetto ResultSet.

Le righe vengono recuperate dal server in blocchi specificati dalla dimensione di recupero.

Tipo di set di risultati (cursore) Tipo di cursore di SQL Server Caratteristiche Metodo select Memorizzazione delle risposte nel buffer
TYPE_SS_DIRECT_FORWARD_ONLY N/D Forward-only, di sola lettura N/D full o adaptive

Valore intero = 2003. Fornisce un cursore sul lato client di sola lettura completamente memorizzato nel buffer. Non viene creato alcun cursore server.

È supportato solo il tipo di concorrenza CONCUR_READ_ONLY. Tutti gli altri tipi di concorrenza generano un'eccezione, se utilizzati con questo tipo di cursore.

Tipo di set di risultati (cursore) Tipo di cursore di SQL Server Caratteristiche Metodo select Memorizzazione delle risposte nel buffer
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY Fast forward Forward-only N/D N/D

Valore intero = 2004. Veloce, con accesso a tutti i dati tramite un cursore server. È aggiornabile quando usato con il tipo di concorrenza CONCUR_UPDATABLE.

Le righe vengono recuperate dal server in blocchi specificati dalla dimensione di recupero.

Per ottenere il buffering adattivo per questo caso, l'applicazione deve chiamare in modo esplicito il metodo setResponseBuffering dell'oggetto SQLServerStatement fornendo un valore stringa "adaptive". Per un esempio di codice, vedere Esempio di aggiornamento di dati di grandi dimensioni.

Tipo di set di risultati (cursore) Tipo di cursore di SQL Server Caratteristiche Metodo select Memorizzazione delle risposte nel buffer
TYPE_SS_SCROLL_STATIC Statico Gli aggiornamenti di altri utenti non vengono riflessi. N/D N/D

Valore intero = 1004. L'applicazione richiede uno snapshot del database. Questa opzione è il sinonimo specifico di SQL Server per l'oggetto JDBC TYPE_SCROLL_INSENSITIVE e presenta lo stesso comportamento dell'impostazione di concorrenza.

Le righe vengono recuperate dal server in blocchi specificati dalla dimensione di recupero.

Tipo di set di risultati (cursore) Tipo di cursore di SQL Server Caratteristiche Metodo select Memorizzazione delle risposte nel buffer
TYPE_SS_SCROLL_KEYSET (CONCUR_READ_ONLY) Keyset Scorrevole, sola lettura. Gli aggiornamenti di righe eseguiti esternamente sono visibili e le eliminazioni vengono visualizzate come dati mancanti.

Gli inserimenti di righe eseguiti esternamente non sono visibili.
N/D N/D

Valore intero = 1005. Nell'applicazione devono essere visualizzati i dati modificati per le righe esistenti. Questa opzione è il sinonimo specifico di SQL Server per l'oggetto JDBC TYPE_SCROLL_SENSITIVE e presenta lo stesso comportamento dell'impostazione di concorrenza.

Le righe vengono recuperate dal server in blocchi specificati dalla dimensione di recupero.

Tipo di set di risultati (cursore) Tipo di cursore di SQL Server Caratteristiche Metodo select Memorizzazione delle risposte nel buffer
TYPE_SS_SCROLL_KEYSET (CONCUR_UPDATABLE, CONCUR_SS_SCROLL_LOCKS, CONCUR_SS_OPTIMISTIC_CC, CONCUR_SS_OPTIMISTIC_CCVAL) Keyset Scorrevole, aggiornabile

Gli aggiornamenti di righe eseguiti internamente ed esternamente sono visibili e le eliminazioni vengono visualizzate come dati mancanti, mentre gli inserimenti non sono visibili.
N/D N/D

Valore intero = 1005. Nell'applicazione devono essere modificati i dati oppure devono essere visualizzati i dati modificati solo per le righe esistenti. Questa opzione è il sinonimo specifico di SQL Server per l'oggetto JDBC TYPE_SCROLL_SENSITIVE e presenta lo stesso comportamento dell'impostazione di concorrenza.

Le righe vengono recuperate dal server in blocchi specificati dalla dimensione di recupero.

Tipo di set di risultati (cursore) Tipo di cursore di SQL Server Caratteristiche Metodo select Memorizzazione delle risposte nel buffer
TYPE_SS_SCROLL_DYNAMIC (CONCUR_READ_ONLY) Dinamico Scorrevole, sola lettura.

Gli aggiornamenti e gli inserimenti di righe eseguiti esternamente sono visibili e le eliminazioni vengono visualizzate come dati mancanti temporanei nel buffer di recupero corrente.
N/D N/D

Valore intero = 1006. Nell'applicazione devono essere visualizzati i dati modificati per le righe esistenti, nonché le righe inserite ed eliminate nel corso della durata del cursore.

Le righe vengono recuperate dal server in blocchi specificati dalla dimensione di recupero.

Tipo di set di risultati (cursore) Tipo di cursore di SQL Server Caratteristiche Metodo select Memorizzazione delle risposte nel buffer
TYPE_SS_SCROLL_DYNAMIC (CONCUR_UPDATABLE, CONCUR_SS_SCROLL_LOCKS, CONCUR_SS_OPTIMISTIC_CC, CONCUR_SS_OPTIMISTIC_CCVAL) Dinamico Scorrevole, aggiornabile

Gli aggiornamenti e gli inserimenti di righe eseguiti esternamente e internamente sono visibili e le eliminazioni vengono visualizzate come dati mancanti temporanei nel buffer di recupero corrente.
N/D N/D

Valore intero = 1006. L'applicazione può modificare i dati per le righe esistenti oppure inserire o eliminare righe tramite l'oggetto ResultSet. L'applicazione deve inoltre essere in grado di visualizzare le modifiche, gli inserimenti e le eliminazioni apportate da altri esternamente all'oggetto ResultSet.

Le righe vengono recuperate dal server in blocchi specificati dalla dimensione di recupero.

Posizionamento dei cursori

I cursori TYPE_FORWARD_ONLY, TYPE_SS_DIRECT_FORWARD_ONLY e TYPE_SS_SERVER_CURSOR_FORWARD_ONLY supportano solo il metodo di posizionamento next.

Il cursore TYPE_SS_SCROLL_DYNAMIC non supporta i metodi absolute e getRow. È possibile ottenere un risultato simile a quello del metodo absolute tramite una combinazione di chiamate ai metodi first e relative per i cursori dinamici.

Il metodo getRow è supportato solo dai cursori TYPE_FORWARD_ONLY, TYPE_SS_DIRECT_FORWARD_ONLY, TYPE_SS_SERVER_CURSOR_FORWARD_ONLY, TYPE_SS_SCROLL_KEYSET e TYPE_SS_SCROLL_STATIC. Il metodo getRow con tutti i tipi di cursore forward-only restituisce il numero di righe lette fino a quel momento tramite il cursore.

Nota

Quando un'applicazione esegue una chiamata non supportata ai metodi di posizionamento del cursore o al metodo getRow, viene generata un'eccezione con il messaggio "L'operazione richiesta non è supportata con questo tipo di cursore".

Solo il cursore TYPE_SS_SCROLL_KEYSET e l'equivalente TYPE_SCROLL_SENSITIVE espongono le righe eliminate. Se il cursore viene posizionato in una riga eliminata, i valori della colonna non sono disponibili e il metodo rowDeleted restituisce "true". Le chiamate dei metodi get<Type> generano un'eccezione con il messaggio "Impossibile ottenere un valore da una riga eliminata". Le righe eliminate non possono essere aggiornate. Se si cerca di chiamare un metodo update<Type> su una riga eliminata, viene generata un'eccezione con il messaggio "Non è possibile aggiornare una riga eliminata". Il cursore TYPE_SS_SCROLL_DYNAMIC ha lo stesso comportamento fino a quando non viene tolto dal buffer di recupero corrente.

I cursori forward e dinamici espongono le righe eliminate in modo simile, ma solo fino a quando rimangono accessibili nel buffer di recupero. Per i cursori di tipo forward, questo comportamento è piuttosto lineare. Per i cursori dinamici, il comportamento è più complesso quando la dimensione di recupero è maggiore di 1. Un'applicazione può spostare il cursore avanti e indietro nella finestra definita dal buffer di recupero, ma la riga eliminata non viene più visualizzata all'uscita dal buffer di recupero originale in cui è stata aggiornata. Se non si vuole che un'applicazione visualizzi le righe eliminate temporanee tramite i cursori dinamici, è necessario usare un'istruzione FETCH RELATIVE con l'argomento 0.

Se i valori chiave della riga di un cursore TYPE_SS_SCROLL_KEYSET o TYPE_SCROLL_SENSITIVE vengono aggiornati con il cursore, la riga mantiene la posizione originale nel set di risultati, indipendentemente dal fatto che la riga aggiornata soddisfi i criteri di selezione del cursore. Se la riga è stata aggiornata all'esterno del cursore, nella posizione originale della riga verrà visualizzata una riga eliminata, ma la riga verrà visualizzata nel cursore solo se nel cursore era presente un'altra riga con i nuovi valori chiave, che tuttavia è stata eliminata.

Per i cursori dinamici, le righe aggiornate mantengono la posizione all'interno del buffer di recupero fino a quando la finestra definita dal buffer di recupero non viene chiusa. Le righe aggiornate possono venire visualizzate in un secondo momento in posizioni diverse nel set di risultati o scomparire completamente. Per le applicazioni in cui è necessario evitare le incoerenze temporanee nel set di risultati, è necessario utilizzare una dimensione di recupero pari a 1. L'impostazione predefinita è 8 righe con concorrenza CONCUR_SS_SCROLL_LOCKS e 128 righe con altre concorrenze.

Conversione dei cursori

SQL Server a volte può scegliere di implementare un tipo di cursore diverso da quello richiesto e questo comportamento è noto come conversione implicita del cursore o degradazione del cursore.

Con SQL Server 2000 (8.x), quando si aggiornano i dati tramite i set di risultati ResultSet.TYPE_SCROLL_SENSITIVE e ResultSet.CONCUR_UPDATABLE, viene generata un'eccezione con un messaggio "Il cursore è READ ONLY". Questa eccezione si verifica perché SQL Server 2000 (8.x) ha eseguito una conversione implicita del cursore per tale set di risultati e non ha restituito il cursore aggiornabile richiesto.

Per risolvere questo problema, è possibile scegliere una delle soluzioni seguenti:

Aggiornamento dei cursori

Gli aggiornamenti sul posto sono supportati per i cursori se la concorrenza e il tipo di cursore supportano gli aggiornamenti. Se il cursore non è posizionato in una riga aggiornabile nel set di risultati (nessuna chiamata del metodo get<Type> ha avuto esito positivo), una chiamata del metodo update<Type> genera un'eccezione con il messaggio "Il set di risultati non ha una riga corrente". La specifica JDBC determina che si verifica un'eccezione quando viene chiamato un metodo di aggiornamento per una colonna di un cursore CONCUR_READ_ONLY. Nei casi in cui la riga non è aggiornabile, ad esempio a causa di un conflitto di concorrenza ottimistica come un aggiornamento o un'eliminazione in conflitto, l'eccezione potrebbe non venire generata fino a quando non viene chiamato il metodo insertRow, updateRow o deleteRow.

Dopo una chiamata di update<Type>, non è possibile accedere alla colonna interessata tramite get<Type> fino a quando non si chiama updateRow o cancelRowUpdates. Questo comportamento consente di evitare i problemi che possono verificarsi quando una colonna viene aggiornata usando un tipo diverso da quello restituito dal server e le chiamate del metodo getter successive possono richiamare conversioni del tipo sul lato client che forniscono risultati non accurati. Le chiamate di get<Type> generano un'eccezione con il messaggio "Impossibile accedere alle colonne aggiornate fino a quando non è stato chiamato updateRow() o cancelRowUpdates()".

Nota

Se il metodo updateRow viene chiamato quando non è stata aggiornata alcuna colonna, il driver JDBC genera un'eccezione con un messaggio che indica che è stato chiamato il metodo updateRow () senza che siano state aggiornate le colonne.

Dopo la chiamata di moveToInsertRow, viene generata un'eccezione se nel set di risultati viene chiamato qualsiasi metodo diverso da get<Type>, update<Type>, insertRow o un metodo di posizionamento del cursore (incluso moveToCurrentRow). Il metodo moveToInsertRow consente di attivare in modo efficace la modalità di inserimento per il set di risultati e i metodi di posizionamento del cursore consentono di interrompere tale modalità. Le chiamate ai metodi di posizionamento relativo del cursore consentono di spostare il cursore rispetto alla posizione in cui si trovava prima della chiamata al metodo moveToInsertRow. Dopo le chiamate ai metodi di posizionamento del cursore, la posizione di destinazione finale del cursore diventa la nuova posizione del cursore.

Se la chiamata ai metodi di posizionamento del cursore eseguita in modalità di inserimento non ha esito positivo, la posizione del cursore dopo tale chiamata corrisponde alla posizione originale del cursore prima della chiamata di moveToInsetRow. Se il metodo insertRow ha esito negativo, il cursore rimane nella riga di inserimento e in modalità di inserimento.

Inizialmente, le colonne nella riga di inserimento hanno uno stato non inizializzato. Le chiamate del metodo update<Type> impostano lo stato delle colonne come inizializzato. Una chiamata del metodo get<Type> per una colonna non inizializzata genera un'eccezione. Una chiamata al metodo insertRow ripristina lo stato non inizializzato per tutte le colonne nella riga di inserimento.

Se quando viene chiamato il metodo insertRow vi sono colonne non inizializzate, in tali colonne viene inserito il relativo valore predefinito. Se non c'è un valore predefinito ma la colonna ammette i valori Null, viene inserito NULL. Se non c'è un valore predefinito e la colonna non ammette i valori Null, il server restituisce un errore e viene generata un'eccezione.

Nota

Le chiamate al metodo getRow eseguite in modalità di inserimento restituiscono 0.

Il driver JDBC non supporta eliminazioni o aggiornamenti posizionati. In base alla specifica JDBC, il metodo setCursorName non ha effetto e il metodo getCursorName quando viene chiamato genera un'eccezione.

I cursori di sola lettura e statici non sono mai aggiornabili.

In SQL Server i cursori server sono limitati a un singolo set di risultati. Se un batch o una stored procedure contiene più istruzioni, è necessario utilizzare un cursore client di sola lettura forward-only.

Vedi anche

Gestione dei set di risultati con il driver JDBC