Funzione SQLSetPos

Conformità
Versione introdotta: Conformità agli standard ODBC 1.0: ODBC

Summary
SQLSetPos imposta la posizione del cursore in un set di righe e consente a un'applicazione di aggiornare i dati nel set di righe o di aggiornare o eliminare i dati nel set di risultati.

Sintassi

  
SQLRETURN SQLSetPos(  
      SQLHSTMT        StatementHandle,  
      SQLSETPOSIROW   RowNumber,  
      SQLUSMALLINT    Operation,  
      SQLUSMALLINT    LockType);  

Argomenti

StatementHandle
[Input] Handle di istruzione.

RowNumber
[Input] Posizione della riga nel set di righe in cui eseguire l'operazione specificata con l'argomento Operation. Se RowNumber è 0, l'operazione viene applicata a ogni riga del set di righe.

Per altre informazioni, vedere "Commenti".

Operazione
[Input] Operazione da eseguire:

SQL_POSITION SQL_REFRESH SQL_UPDATE SQL_DELETE

Nota

Il SQL_ADD per l'argomento Operation è stato deprecato per ODBC 3.x. I driver ODBC 3.x dovranno supportare l'SQL_ADD per la compatibilità con le versioni precedenti. Questa funzionalità è stata sostituita da una chiamata a SQLBulkOperations con un'operazione di SQL_ADD. Quando un'applicazione ODBC 3.x funziona con un driver ODBC 2.x, Gestione driver esegue il mapping di una chiamata a SQLBulkOperations con un'operazione di SQL_ADD a SQLSetPos con un'operazione di SQL_ADD.

Per altre informazioni, vedere "Commenti".

Locktype
[Input] Specifica come bloccare la riga dopo l'esecuzione dell'operazione specificata nell'argomento Operation.

SQL_LOCK_NO_CHANGE SQL_LOCK_EXCLUSIVE SQL_LOCK_UNLOCK

Per altre informazioni, vedere "Commenti".

Restituisce

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR o SQL_INVALID_HANDLE.

Diagnostica

Quando SQLSetPos restituisce SQL_ERROR o SQL_SUCCESS_WITH_INFO, è possibile ottenere un valore SQLSTATE associato chiamando SQLGetDiagRec con handleType SQL_HANDLE_STMT e Handle di StatementHandle. La tabella seguente elenca i valori SQLSTATE comunemente restituiti da SQLSetPos e ne illustra ognuno nel contesto di questa funzione. la notazione "(DM)" precede le descrizioni di SQLSTATE restituite da Gestione driver. Il codice restituito associato a ogni valore SQLSTATE è SQL_ERROR, se non specificato diversamente.

Per tutti gli SQLSTATE che possono restituire SQL_SUCCESS_WITH_INFO o SQL_ERROR (ad eccezione di 01xxx SQLSTATEs), viene restituito SQL_SUCCESS_WITH_INFO se si verifica un errore in una o più righe, ma non in tutte le righe di un'operazione su più righe, e viene restituito SQL_ERROR se si verifica un errore in un'operazione a riga singola.

SQLSTATE Errore Descrizione
01000 Avviso generale Messaggio informativo specifico del driver. La funzione restituisce SQL_SUCCESS_WITH_INFO.
01001 Conflitto di operazioni del cursore L'argomento Operation SQL_DELETE o SQL_UPDATE e nessuna riga o più righe sono state eliminate o aggiornate. Per altre informazioni sugli aggiornamenti a più righe, vedere la descrizione dell'attributo SQL_ATTR_SIMULATE_CURSOR in SQLSetStmtAttr. La funzione restituisce SQL_SUCCESS_WITH_INFO.

L'argomento Operation è SQL_DELETE o SQL_UPDATE e l'operazione non è riuscita a causa della concorrenza ottimistica. La funzione restituisce SQL_SUCCESS_WITH_INFO.
01004 Troncamento a destra dei dati stringa L'argomento Operation è SQL_REFRESH e i dati stringa o binari restituiti per una o più colonne con tipo di dati SQL_C_CHAR o SQL_C_BINARY hanno comportato il troncamento di dati binari di tipo carattere non vuoto o non NULL.
01S01 Errore nella riga L'argomento RowNumber era 0 e si è verificato un errore in una o più righe durante l'esecuzione dell'operazione specificata con l'argomento Operation.

(SQL_SUCCESS_WITH_INFO viene restituito se si verifica un errore in una o più righe, ma non in tutte le righe di un'operazione su più righe, e se si verifica un errore in un'operazione su una sola riga viene restituito SQL_ERROR).

Questo valore SQLSTATE viene restituito solo quando SQLSetPos viene chiamato dopo SQLExtendedFetch, se il driver è un driver ODBC 2.x e la libreria di cursori non viene usata.
01S07 Troncamento frazionario L'argomento Operation SQL_REFRESH, il tipo di dati del buffer dell'applicazione non è SQL_C_CHAR o SQL_C_BINARY e i dati restituiti ai buffer dell'applicazione per una o più colonne sono stati troncati. Per i tipi di dati numerici, la parte frazionaria del numero è stata troncata. Per i tipi di dati time, timestamp e interval contenenti un componente relativo all'ora, la parte frazionaria dell'ora è stata troncata.

La funzione restituisce SQL_SUCCESS_WITH_INFO.
07006 Violazione dell'attributo del tipo di dati con restrizioni Non è stato possibile convertire il valore di dati di una colonna nel set di risultati nel tipo di dati specificato da TargetType nella chiamata a SQLBindCol.
07009 Indice descrittore non valido L'argomento Operation SQL_REFRESH o SQL_UPDATE ed è stata associata una colonna con un numero di colonna maggiore del numero di colonne nel set di risultati.
21S02 Grado di tabella derivata non corrispondente all'elenco di colonne L'argomento Operation è SQL_UPDATE e nessuna colonna è aggiornabile perché tutte le colonne non sono associate, sono di sola lettura o il valore nel buffer di lunghezza/indicatore associato è SQL_COLUMN_IGNORE.
22001 Dati stringa, troncamento a destra L'argomento Operation è SQL_UPDATE e l'assegnazione di un carattere o di un valore binario a una colonna ha comportato il troncamento di caratteri o byte non vuoti (per i caratteri) o non Null (per i caratteri binari).
22003 Valore numerico non compreso nell'intervallo L'argomento Operation è SQL_UPDATE e l'assegnazione di un valore numerico a una colonna nel set di risultati ha causato il troncamento dell'intera parte del numero, anziché frazionaria.

L'argomento Operation è SQL_REFRESH e la restituzione del valore numerico per una o più colonne associate avrebbe causato una perdita di cifre significative.
22007 Formato datetime non valido L'argomento Operation è SQL_UPDATE e l'assegnazione di un valore di data o timestamp a una colonna nel set di risultati ha causato l'esterno dell'intervallo del campo anno, mese o giorno.

L'argomento Operation è SQL_REFRESH e la restituzione del valore di data o timestamp per una o più colonne associate avrebbe causato l'esterno dell'intervallo del campo year, month o day.
22008 Overflow del campo di data/ora L'argomento Operation è SQL_UPDATE e le prestazioni dell'aritmetica datetime sui dati inviati a una colonna nel set di risultati hanno restituito un campo datetime (anno, mese, giorno, ora, minuto o secondo campo) del risultato che non rientra nell'intervallo consentito di valori per il campo o non è valido in base alle regole naturali del calendario gregoriano per i valori datetime.

L'argomento Operation è SQL_REFRESH e le prestazioni dell'aritmetica datetime sui dati recuperati dal set di risultati hanno restituito un campo datetime (anno, mese, giorno, ora, minuto o secondo campo) del risultato che non rientra nell'intervallo consentito di valori per il campo o non è valido in base alle regole naturali del calendario gregoriano per datetimes.
22015 Overflow del campo intervallo L'argomento Operation è SQL_UPDATE e l'assegnazione di un tipo numerico o intervallo C esatto a un tipo di dati interval SQL ha causato la perdita di cifre significative.

L'argomento Operation è SQL_UPDATE; Quando si assegna a un tipo SQL intervallo, non è presente alcuna rappresentazione del valore del tipo C nell'intervallo SQL tipo.

L'argomento Operation è SQL_REFRESH e l'assegnazione da un tipo numerico o intervallo esatto SQL un tipo intervallo C ha causato la perdita di cifre significative nel campo iniziale.

L'argomento Operation è SQL_ REFRESH; Quando si esegue l'assegnazione a un tipo intervallo C, non è presente alcuna rappresentazione del valore del tipo SQL nel tipo interval C.
22018 Valore di carattere non valido per la specifica del cast L'argomento Operation è stato SQL_REFRESH; il tipo C era un tipo di dati numerico esatto o approssimativo, un tipo di dati datetime o interval; il SQL della colonna era un tipo di dati carattere. e il valore nella colonna non è un valore letterale valido del tipo C associato.

L'argomento Operation è stato SQL_UPDATE; il SQL è un tipo di dati numerico esatto o approssimativo, un tipo di dati datetime o interval; Il tipo C è stato SQL_C_CHAR; e il valore nella colonna non è un valore letterale valido del tipo SQL associato.
23000 Violazione del vincolo di integrità L'argomento Operation è SQL_DELETE o SQL_UPDATE ed è stato violato un vincolo di integrità.
24000 Stato del cursore non valido StatementHandle era in uno stato eseguito, ma nessun set di risultati è stato associato a StatementHandle.

(DM) Un cursore è stato aperto in StatementHandle, ma non è stato chiamato SQLFetch o SQLFetchScroll.

È stato aperto un cursore in StatementHandle ed è stato chiamato SQLFetch o SQLFetchScroll, ma il cursore è stato posizionato prima dell'inizio del set di risultati o dopo la fine del set di risultati.

L'argomento Operation è SQL_DELETE, SQL_REFRESH o SQL_UPDATE e il cursore è stato posizionato prima dell'inizio del set di risultati o dopo la fine del set di risultati.
40001 Errore di serializzazione È stato eseguito il rollback della transazione a causa di un deadlock delle risorse con un'altra transazione.
40003 Completamento istruzioni sconosciuto La connessione associata non è riuscita durante l'esecuzione di questa funzione e non è possibile determinare lo stato della transazione.
42000 Errore di sintassi o violazione di accesso Il driver non è riuscito a bloccare la riga in base alle esigenze per eseguire l'operazione richiesta nell'argomento Operation.

Il driver non è riuscito a bloccare la riga come richiesto nell'argomento LockType.
44000 Violazione della clausola WITH CHECK OPTION L'argomento Operation è SQL_UPDATE e l'aggiornamento è stato eseguito in una tabella visualizzata o in una tabella derivata dalla tabella visualizzata creata specificando WITH CHECK OPTION, in modo che una o più righe interessate dall'aggiornamento non siano più presenti nella tabella visualizzata.
HY000 Errore generale: Si è verificato un errore per il quale non esiste un SQLSTATE specifico e per il quale non è stato definito sqlSTATE specifico dell'implementazione. Il messaggio di errore restituito da SQLGetDiagRec nel buffer * MessageText descrive l'errore e la relativa causa.
HY001 Errore di allocazione della memoria Il driver non è riuscito ad allocare la memoria necessaria per supportare l'esecuzione o il completamento della funzione.
HY008 Operation canceled L'elaborazione asincrona è stata abilitata per StatementHandle. La funzione è stata chiamata e prima del completamento dell'esecuzione, SQLCancel o SQLCancelHandle è stato chiamato su StatementHandle e quindi la funzione è stata chiamata nuovamente su StatementHandle.

La funzione è stata chiamata e prima del completamento dell'esecuzione è stato chiamato SQLCancel o SQLCancelHandle su StatementHandle da un thread diverso in un'applicazione multithreading.
HY010 Errore della sequenza di funzione (DM) È stata chiamata una funzione in esecuzione in modo asincrono per l'handle di connessione associato a StatementHandle. Questa funzione asincrona era ancora in esecuzione quando è stata chiamata la funzione SQLSetPos.

(DM) L'oggetto StatementHandle specificato non è in uno stato eseguito. La funzione è stata chiamata senza prima chiamare SQLExecDirect, SQLExecute o una funzione di catalogo.

(DM) Una funzione in esecuzione in modo asincrono (non questa) è stata chiamata per StatementHandle ed era ancora in esecuzione quando è stata chiamata questa funzione.

(DM) SQLExecute, SQLExecDirect, SQLBulkOperations o SQLSetPos sono stati chiamati per StatementHandle e sono stati restituiti SQL_NEED_DATA. Questa funzione è stata chiamata prima dell'invio dei dati per tutti i parametri o le colonne data-at-execution.

(DM) Il driver era un driver ODBC 2.x ed è stato chiamato SQLSetPos per statementHandle dopo la chiamata a SQLFetch.
HY011 L'attributo non può essere impostato ora (DM) Il driver era un driver ODBC 2.x; L'SQL_ATTR_ROW_STATUS_PTR'attributo dell'istruzione è stato impostato; sqlSetPos è stato chiamato prima della chiamata a SQLFetch, SQLFetchScroll o SQLExtendedFetch.
HY013 Errore di gestione della memoria Non è stato possibile elaborare la chiamata di funzione perché non è stato possibile accedere agli oggetti di memoria sottostanti, probabilmente a causa di condizioni di memoria insufficiente.
HY090 Lunghezza di stringa o buffer non valida L'argomento Operation è SQL_UPDATE, un valore di dati è un puntatore Null e il valore della lunghezza della colonna non è 0, SQL_DATA_AT_EXEC, SQL_COLUMN_IGNORE, SQL_NULL_DATA o minore o uguale a SQL_LEN_DATA_AT_EXEC_OFFSET.

L'argomento Operation è stato SQL_UPDATE; un valore di dati non è un puntatore Null. il tipo di dati C è SQL_C_BINARY o SQL_C_CHAR; e la lunghezza della colonna è minore di 0 ma non uguale a SQL_DATA_AT_EXEC, SQL_COLUMN_IGNORE, SQL_NTS o SQL_NULL_DATA oppure minore o uguale a SQL_LEN_DATA_AT_EXEC_OFFSET.

Il valore in un buffer di lunghezza/indicatore è stato SQL_DATA_AT_EXEC; il SQL di dati era SQL_LONGVARCHAR, SQL_LONGVARBINARY o un tipo di dati long specifico dell'origine dati; e il SQL_NEED_LONG_DATA_LEN di informazioni in SQLGetInfo è "Y".
HY092 Identificatore di attributo non valido (DM) Il valore specificato per l'argomento Operation non è valido.

(DM) Il valore specificato per l'argomento LockType non è valido.

L'argomento Operation è SQL_UPDATE o SQL_DELETE e l'attributo dell'istruzione SQL_ATTR_CONCURRENCY è stato SQL_ATTR_CONCUR_READ_ONLY.
HY107 Valore di riga non compreso nell'intervallo Il valore specificato per l'argomento RowNumber è maggiore del numero di righe nel set di righe.
HY109 Posizione del cursore non valida Il cursore associato a StatementHandle è stato definito come forward-only, quindi non è stato possibile posizionare il cursore all'interno del set di righe. Vedere la descrizione dell'SQL_ATTR_CURSOR_TYPE in SQLSetStmtAttr.

L'argomento Operation SQL_UPDATE, SQL_DELETE o SQL_REFRESH e la riga identificata dall'argomento RowNumber è stata eliminata o non è stata recuperata.

(DM) L'argomento RowNumber è 0 e l'argomento Operation è SQL_POSITION.

SQLSetPos è stato chiamato dopo la chiamata di SQLBulkOperations e prima della chiamata a SQLFetchScroll o SQLFetch.
HY117 La connessione è stata sospesa a causa di uno stato di transazione sconosciuto. Sono consentite solo le funzioni di disconnessione e di sola lettura. (DM) Per altre informazioni sullo stato sospeso, vedere Funzione SQLEndTran.
HYC00 Funzionalità facoltativa non implementata Il driver o l'origine dati non supporta l'operazione richiesta nell'argomento Operation o LockType.
HYT00 Timeout Il periodo di timeout della query è scaduto prima che l'origine dati restituisce il set di risultati. Il periodo di timeout viene impostato tramite SQLSetStmtAttr con un attributo SQL_ATTR_QUERY_TIMEOUT.
HYT01 Timeout della connessione scaduto Il periodo di timeout della connessione è scaduto prima che l'origine dati risponda alla richiesta. Il periodo di timeout della connessione viene impostato tramite SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Il driver non supporta questa funzione (DM) Il driver associato a StatementHandle non supporta la funzione .
IM017 Il polling è disabilitato in modalità di notifica asincrona Ogni volta che viene usato il modello di notifica, il polling è disabilitato.
IM018 SQLCompleteAsync non è stato chiamato per completare l'operazione asincrona precedente su questo handle. Se la chiamata di funzione precedente sull'handle restituisce SQL_STILL_EXECUTING e se la modalità di notifica è abilitata, è necessario chiamare SQLCompleteAsync sull'handle per eseguire la post-elaborazione e completare l'operazione.

Commenti

Attenzione

Per informazioni sugli stati dell'istruzione in cui è possibile chiamare SQLSetPos e sulle relative funzionalità per la compatibilità con le applicazioni ODBC 2.x, vedere Cursori a blocchi, cursoriscorrevoli e Compatibilità con le versioni precedenti.

Argomento RowNumber

L'argomento RowNumber specifica il numero della riga nel set di righe in cui eseguire l'operazione specificata dall'argomento Operation. Se RowNumber è 0, l'operazione viene applicata a ogni riga del set di righe. RowNumber deve essere un valore compreso tra 0 e il numero di righe nel set di righe.

Nota

Nel linguaggio C le matrici sono in base 0 e l'argomento RowNumber è in base 1. Ad esempio, per aggiornare la quinta riga del set di righe, un'applicazione modifica i buffer del set di righe in corrispondenza dell'indice di matrice 4, ma specifica un valore RowNumber di 5.

Tutte le operazioni posizionano il cursore sulla riga specificata da RowNumber. Le operazioni seguenti richiedono una posizione del cursore:

  • Istruzioni di aggiornamento ed eliminazione posizionate.

  • Chiama a SQLGetData.

  • Chiama a SQLSetPos con le SQL_DELETE, SQL_REFRESH e SQL_UPDATE seguenti.

Ad esempio, se RowNumber è 2 per una chiamata a SQLSetPos con un'operazione di SQL_DELETE, il cursore viene posizionato sulla seconda riga del set di righe e tale riga viene eliminata. La voce nella matrice dello stato della riga di implementazione (a cui punta l'attributo dell'istruzione SQL_ATTR_ROW_STATUS_PTR) per la seconda riga viene modificata in SQL_ROW_DELETED.

Un'applicazione può specificare una posizione del cursore quando chiama SQLSetPos. In genere, chiama SQLSetPos con l'operazione SQL_POSITION o SQL_REFRESH per posizionare il cursore prima di eseguire un'istruzione di aggiornamento o eliminazione posizionata o chiamare SQLGetData.

Argomento Operation

L'argomento Operation supporta le operazioni seguenti. Per determinare quali opzioni sono supportate da un'origine dati, un'applicazione chiama SQLGetInfo con il tipo di informazioni SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, SQL_KEYSET_CURSOR_ATTRIBUTES1 o SQL_STATIC_CURSOR_ATTRIBUTES1 (a seconda del tipo di cursore).

Operazione

argomento
Operazione
SQL_POSITION Il driver posiziona il cursore sulla riga specificata da RowNumber.

Il contenuto della matrice di stato della riga a cui punta l'attributo SQL_ATTR_ROW_OPERATION_PTR'istruzione viene ignorato per l'SQL_POSITION.
SQL_REFRESH Il driver posiziona il cursore sulla riga specificata da RowNumber e aggiorna i dati nei buffer del set di righe per tale riga. Per altre informazioni sul modo in cui il driver restituisce i dati nei buffer del set di righe, vedere le descrizioni dell'associazione per riga e colonna in SQLBindCol.

SQLSetPos con un'operazione di SQL_REFRESH aggiorna lo stato e il contenuto delle righe all'interno del set di righe recuperato corrente. Ciò include l'aggiornamento dei segnalibri. Poiché i dati nei buffer vengono aggiornati ma non aggiornati, l'appartenenza al set di righe è fissa. Questo è diverso dall'aggiornamento eseguito da una chiamata a SQLFetchScroll con FetchOrientation di SQL_FETCH_RELATIVE e RowNumber uguale a 0, che recupera il set di righe dal set di risultati in modo che possa visualizzare i dati aggiunti e rimuovere i dati eliminati se tali operazioni sono supportate dal driver e dal cursore.

Un aggiornamento riuscito con SQLSetPos non modifica lo stato della riga SQL_ROW_DELETED. Le righe eliminate all'interno del set di righe continueranno a essere contrassegnate come eliminate fino al recupero successivo. Le righe non verranno più recuperate al recupero successivo se il cursore supporta la creazione di un pacchetto (in cui un'istruzione SQLFetch o SQLFetchScroll successiva non restituisce righe eliminate).

Le righe aggiunte non vengono visualizzate quando viene eseguito un aggiornamento con SQLSetPos. Questo comportamento è diverso da SQLFetchScroll con FetchType SQL_FETCH_RELATIVE e RowNumber uguale a 0, che aggiorna anche il set di righe corrente, ma mostra i record aggiunti o i record eliminati di tipo pack se queste operazioni sono supportate dal cursore.

Un aggiornamento riuscito con SQLSetPos modificherà lo stato della riga SQL_ROW_ADDED in SQL_ROW_SUCCESS (se la matrice di stato della riga esiste).

Un aggiornamento riuscito con SQLSetPos modificherà lo stato della riga SQL_ROW_UPDATED al nuovo stato della riga (se la matrice di stato della riga esiste).

Se si verifica un errore in un'operazione SQLSetPos su una riga, lo stato della riga viene impostato su SQL_ROW_ERROR (se la matrice di stato della riga esiste).

Per un cursore aperto con un attributo di istruzione SQL_ATTR_CONCURRENCY di SQL_CONCUR_ROWVER o SQL_CONCUR_VALUES, un aggiornamento con SQLSetPos potrebbe aggiornare i valori di concorrenza ottimistica usati dall'origine dati per rilevare che la riga è stata modificata. In questo caso, le versioni di riga o i valori utilizzati per garantire la concorrenza del cursore vengono aggiornati ogni volta che i buffer del set di righe vengono aggiornati dal server. Ciò si verifica per ogni riga aggiornata.

Il contenuto della matrice di stato della riga a cui punta l'attributo SQL_ATTR_ROW_OPERATION_PTR'istruzione viene ignorato per l SQL_REFRESH o operazione.
SQL_UPDATE Il driver posiziona il cursore sulla riga specificata da RowNumber e aggiorna la riga di dati sottostante con i valori nei buffer del set di righe (argomento TargetValuePtr in SQLBindCol). Recupera le lunghezze dei dati dai buffer di lunghezza/indicatore (l'argomento StrLen_or_IndPtr in SQLBindCol). Se la lunghezza di una colonna è SQL_COLUMN_IGNORE, la colonna non viene aggiornata. Dopo l'aggiornamento della riga, il driver modifica l'elemento corrispondente della matrice di stato della riga in SQL_ROW_UPDATED o SQL_ROW_SUCCESS_WITH_INFO (se la matrice di stato della riga esiste).

Il comportamento è definito dal driver se SQLSetPos con un argomento Operation SQL_UPDATE viene chiamato su un cursore che contiene colonne duplicate. Il driver può restituire un valore SQLSTATE definito dal driver, può aggiornare la prima colonna visualizzata nel set di risultati o eseguire un altro comportamento definito dal driver.

La matrice dell'operazione di riga a cui punta l'attributo dell'istruzione SQL_ATTR_ROW_OPERATION_PTR può essere usata per indicare che una riga nel set di righe corrente deve essere ignorata durante un aggiornamento bulk. Per altre informazioni, vedere "Stato e matrici di operazioni" più avanti in questo riferimento alla funzione.
SQL_DELETE Il driver posiziona il cursore sulla riga specificata da RowNumber ed elimina la riga di dati sottostante. Modifica l'elemento corrispondente della matrice di stato della riga in SQL_ROW_DELETED. Dopo l'eliminazione della riga, gli elementi seguenti non sono validi per la riga: istruzioni di aggiornamento ed eliminazione posizionate, chiamate a SQLGetData e chiamate a SQLSetPos con Operation impostato su qualsiasi elemento ad eccezione di SQL_POSITION. Per i driver che supportano la creazione di un pacchetto, la riga viene eliminata dal cursore quando vengono recuperati nuovi dati dall'origine dati.

La visibilità della riga dipende dal tipo di cursore. Ad esempio, le righe eliminate sono visibili ai cursori statici e guidati da keyset, ma invisibili ai cursori dinamici.

La matrice dell'operazione di riga a cui punta l'attributo dell'istruzione SQL_ATTR_ROW_OPERATION_PTR può essere usata per indicare che una riga nel set di righe corrente deve essere ignorata durante un'eliminazione bulk. Per altre informazioni, vedere "Stato e matrici di operazioni" più avanti in questo riferimento alla funzione.

Argomento LockType

L'argomento LockType consente alle applicazioni di controllare la concorrenza. Nella maggior parte dei casi, le origini dati che supportano i livelli di concorrenza e le transazioni supporteranno solo il valore SQL_LOCK_NO_CHANGE dell'argomento LockType . L'argomento LockType viene in genere usato solo per il supporto basato su file.

L'argomento LockType specifica lo stato di blocco della riga dopo l'esecuzione di SQLSetPos. Se il driver non è in grado di bloccare la riga per eseguire l'operazione richiesta o per soddisfare l'argomento LockType, restituisce SQL_ERROR e SQLSTATE 42000 (errore di sintassi o violazione di accesso).

Anche se l'argomento LockType viene specificato per una singola istruzione, il blocco consente di ottenere gli stessi privilegi per tutte le istruzioni sulla connessione. In particolare, un blocco acquisito da un'istruzione su una connessione può essere sbloccato da un'istruzione diversa nella stessa connessione.

Una riga bloccata tramite SQLSetPos rimane bloccata fino a quando l'applicazione non chiama SQLSetPos per la riga con LockType impostato su SQL_LOCK_UNLOCK o fino a quando l'applicazione non chiama SQLFreeHandle per l'istruzione o SQLFreeStmt con l'opzione SQL_CLOSE. Per un driver che supporta le transazioni, una riga bloccata tramite SQLSetPos viene sbloccata quando l'applicazione chiama SQLEndTran per eseguire il commit o il rollback di una transazione sulla connessione (se un cursore viene chiuso quando viene eseguito il commit o il rollback di una transazione, come indicato dai tipi di informazioni SQL_CURSOR_COMMIT_BEHAVIOR e SQL_CURSOR_ROLLBACK_BEHAVIOR restituiti da SQLGetInfo).

L'argomento LockType supporta i tipi di blocchi seguenti. Per determinare quali blocchi sono supportati da un'origine dati, un'applicazione chiama SQLGetInfo con il tipo di informazioni SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, SQL_KEYSET_CURSOR_ATTRIBUTES1 o SQL_STATIC_CURSOR_ATTRIBUTES1 (a seconda del tipo di cursore).

Argomento LockType Tipo di blocco
SQL_LOCK_NO_CHANGE Il driver o l'origine dati garantisce che la riga si trova nello stesso stato bloccato o sbloccato prima della chiamata a SQLSetPos. Questo valore di LockType consente alle origini dati che non supportano il blocco esplicito a livello di riga di utilizzare qualsiasi blocco richiesto dai livelli di concorrenza e isolamento delle transazioni correnti.
SQL_LOCK_EXCLUSIVE Il driver o l'origine dati blocca esclusivamente la riga. Non è possibile utilizzare un'istruzione in una connessione diversa o in un'altra applicazione per acquisire blocchi sulla riga.
SQL_LOCK_UNLOCK Il driver o l'origine dati sblocca la riga.

Se un driver supporta SQL_LOCK_EXCLUSIVE ma non supporta SQL_LOCK_UNLOCK, una riga bloccata rimarrà bloccata fino a quando non si verifica una delle chiamate di funzione descritte nel paragrafo precedente.

Se un driver supporta SQL_LOCK_EXCLUSIVE ma non supporta SQL_LOCK_UNLOCK, una riga bloccata rimarrà bloccata fino a quando l'applicazione non chiama SQLFreeHandle per l'istruzione o SQLFreeStmt con l'opzione SQL_CLOSE. Se il driver supporta le transazioni e chiude il cursore al momento del commit o del rollback della transazione, l'applicazione chiama SQLEndTran.

Per le operazioni di aggiornamento ed eliminazione in SQLSetPos, l'applicazione usa l'argomento LockType come indicato di seguito:

  • Per garantire che una riga non cambi dopo il recupero, un'applicazione chiama SQLSetPos con Operation impostato su SQL_REFRESH e LockType impostato su SQL_LOCK_EXCLUSIVE.

  • Se l'applicazione imposta LockType su SQL_LOCK_NO_CHANGE, il driver garantisce che un'operazione di aggiornamento o eliminazione avrà esito positivo solo se l'applicazione ha specificato SQL_CONCUR_LOCK per l'attributo dell'istruzione SQL_ATTR_CONCURRENCY.

  • Se l'applicazione specifica SQL_CONCUR_ROWVER o SQL_CONCUR_VALUES per l'attributo dell'istruzione SQL_ATTR_CONCURRENCY, il driver confronta le versioni o i valori di riga e rifiuta l'operazione se la riga è stata modificata dopo che l'applicazione ha recuperato la riga.

  • Se l'applicazione specifica SQL_CONCUR_READ_ONLY per l'attributo SQL_ATTR_CONCURRENCY, il driver rifiuta qualsiasi operazione di aggiornamento o eliminazione.

Per altre informazioni sull'attributo SQL_ATTR_CONCURRENCY'istruzione , vedere SQLSetStmtAttr.

Matrici di stato e operazioni

Le matrici di stato e di operazione seguenti vengono usate quando si chiama SQLSetPos:

  • La matrice dello stato della riga (a cui punta il campo SQL_DESC_ARRAY_STATUS_PTR nell'IRD e nell'attributo dell'istruzione SQL_ATTR_ROW_STATUS_ARRAY) contiene i valori di stato per ogni riga di dati nel set di righe. Il driver imposta i valori di stato in questa matrice dopo una chiamata a SQLFetch, SQLFetchScroll, SQLBulkOperations o SQLSetPos. Questa matrice è a cui punta l'attributo SQL_ATTR_ROW_STATUS_PTR'istruzione .

  • La matrice dell'operazione di riga (a cui punta il campo SQL_DESC_ARRAY_STATUS_PTR nell'attributo ARD e nell'istruzione SQL_ATTR_ROW_OPERATION_ARRAY) contiene un valore per ogni riga del set di righe che indica se una chiamata a SQLSetPos per un'operazione bulk viene ignorata o eseguita. Ogni elemento nella matrice è impostato su SQL_ROW_PROCEED (impostazione predefinita) o SQL_ROW_IGNORE. Questa matrice è a cui punta l'attributo SQL_ATTR_ROW_OPERATION_PTR'istruzione .

Il numero di elementi nelle matrici dello stato e dell'operazione deve essere uguale al numero di righe nel set di righe (come definito dall'attributo SQL_ATTR_ROW_ARRAY_SIZE'istruzione ).

Per informazioni sulla matrice dello stato della riga, vedere SQLFetch. Per informazioni sulla matrice dell'operazione di riga, vedere "Ignorare una riga in un'operazione bulk" più avanti in questa sezione.

Uso di SQLSetPos

Prima che un'applicazione chiami SQLSetPos, deve eseguire la sequenza di passaggi seguente:

  1. Se l'applicazione chiamerà SQLSetPos con Operation impostato su SQL_UPDATE, chiamare SQLBindCol (o SQLSetDescRec) per ogni colonna per specificare il tipo di dati e associare i buffer per i dati e la lunghezza della colonna.

  2. Se l'applicazione chiamerà SQLSetPos con Operation impostato su SQL_DELETE o SQL_UPDATE, chiamare SQLColAttribute per assicurarsi che le colonne da eliminare o aggiornare siano aggiornabili.

  3. Chiamare SQLExecDirect, SQLExecute o una funzione di catalogo per creare un set di risultati.

  4. Chiamare SQLFetch o SQLFetchScroll per recuperare i dati.

Per altre informazioni sull'uso di SQLSetPos, vedere Aggiornamento di dati con SQLSetPos.

Eliminazione di dati tramite SQLSetPos

Per eliminare dati con SQLSetPos, un'applicazione chiama SQLSetPos con RowNumber impostato sul numero della riga da eliminare e Operation impostato su SQL_DELETE.

Dopo l'eliminazione dei dati, il driver modifica il valore nella matrice di stato della riga di implementazione per la riga appropriata in SQL_ROW_DELETED (o SQL_ROW_ERROR).

Aggiornamento di dati tramite SQLSetPos

Un'applicazione può passare il valore di una colonna nel buffer di dati associato o con una o più chiamate a SQLPutData. Le colonne i cui dati vengono passati con SQLPutData sono note come colonne data-at-execution . Questi vengono comunemente usati per inviare dati per SQL_LONGVARBINARY e SQL_LONGVARCHAR colonne e possono essere misti con altre colonne.

Per aggiornare i dati con SQLSetPos, un'applicazione:

  1. Inserisce i valori nei buffer di dati e lunghezza/indicatore associati a SQLBindCol:

    • Per le colonne normali, l'applicazione inserisce il nuovo valore della colonna nel buffer * TargetValuePtr e la lunghezza di tale valore nel buffer * StrLen_or_IndPtr dati. Se la riga non deve essere aggiornata, l'applicazione inserisce SQL_ROW_IGNORE nell'elemento della riga della matrice dell'operazione di riga.

    • Per le colonne data-at-execution, l'applicazione inserisce un valore definito dall'applicazione, ad esempio il numero di colonna, nel buffer * TargetValuePtr. Il valore può essere usato in un secondo momento per identificare la colonna.

      L'applicazione inserisce il risultato della macro SQL_LEN_DATA_AT_EXEC(length) nel buffer di StrLen_or_IndPtr * . Se il tipo di dati SQL della colonna è SQL_LONGVARBINARY, SQL_LONGVARCHAR o un tipo di dati long specifico dell'origine dati e il driver restituisce "Y" per il tipo di informazioni SQL_NEED_LONG_DATA_LEN in SQLGetInfo, length è il numero di byte di dati da inviare per il parametro. in caso contrario, deve essere un valore non negativo e viene ignorato.

  2. Chiama SQLSetPos con l'argomento Operation impostato SQL_UPDATE per aggiornare la riga di dati.

    • Se non sono presenti colonne di dati in fase di esecuzione, il processo è completo.

    • Se sono presenti colonne di dati in fase di esecuzione, la funzione restituisce SQL_NEED_DATA e procede al passaggio 3.

  3. Chiama SQLParamData per recuperare l'indirizzo del buffer * TargetValuePtr per la prima colonna data-at-execution da elaborare. SQLParamData restituisce SQL_NEED_DATA. L'applicazione recupera il valore definito dall'applicazione dal buffer * TargetValuePtr.

    Nota

    Anche se i parametri data-at-execution sono simili alle colonne data-at-execution, il valore restituito da SQLParamData è diverso per ognuna.

    Nota

    I parametri data-at-execution sono parametri in un'istruzione SQL per cui i dati verranno inviati con SQLPutData quando l'istruzione viene eseguita con SQLExecDirect o SQLExecute. Sono associati a SQLBindParameter o impostando i descrittori con SQLSetDescRec. Il valore restituito da SQLParamData è un valore a 32 bit passato a SQLBindParameter nell'argomento ParameterValuePtr.

    Nota

    Le colonne di dati in fase di esecuzione sono colonne di un set di righe per cui i dati verranno inviati con SQLPutData quando una riga viene aggiornata con SQLSetPos. Sono associati a SQLBindCol. Il valore restituito da SQLParamData è l'indirizzo della riga nel buffer *TargetValuePtr che viene elaborato.

  4. Chiama SQLPutData una o più volte per inviare dati per la colonna. Sono necessarie più chiamate se non è possibile restituire tutti i valori di dati nel buffer * TargetValuePtr specificato in SQLPutData. Più chiamate a SQLPutData per la stessa colonna sono consentite solo quando si inviano dati di tipo carattere C a una colonna con un tipo di dati carattere, binario o specifico dell'origine dati o quando si inviano dati binari C a una colonna con un carattere, tipo di dati binario o specifico dell'origine dati.

  5. Chiama nuovamente SQLParamData per segnalare che tutti i dati sono stati inviati per la colonna.

    • Se sono presenti più colonne data-at-execution, SQLParamData restituisce SQL_NEED_DATA e l'indirizzo del buffer TargetValuePtr per l'elaborazione della colonna data-at-execution successiva. L'applicazione ripete i passaggi 4 e 5.

    • Se non sono presenti altre colonne data-at-execution, il processo è completo. Se l'istruzione è stata eseguita correttamente, SQLParamData restituisce SQL_SUCCESS o SQL_SUCCESS_WITH_INFO; se l'esecuzione non è riuscita, restituisce SQL_ERROR. A questo punto, SQLParamData può restituire qualsiasi SQLSTATE che può essere restituito da SQLSetPos.

Se i dati sono stati aggiornati, il driver modifica il valore nella matrice di stato della riga di implementazione per la riga appropriata SQL_ROW_UPDATED.

Se l'operazione viene annullata o si verifica un errore in SQLParamData o SQLPutData, dopo che SQLSetPos restituisce SQL_NEED_DATA e prima che i dati vengono inviati per tutte le colonne di dati in fase di esecuzione, l'applicazione può chiamare solo SQLCancel, SQLGetDiagField, SQLGetDiagRec, SQLGetFunctions, SQLParamData o SQLPutData per l'istruzione o la connessione associata all'istruzione . Se chiama qualsiasi altra funzione per l'istruzione o la connessione associata all'istruzione , la funzione restituisce SQL_ERROR e SQLSTATE HY010 (errore della sequenza di funzioni).

Se l'applicazione chiama SQLCancel mentre il driver necessita ancora di dati per le colonne di dati in fase di esecuzione, il driver annulla l'operazione. L'applicazione può quindi chiamare nuovamente SQLSetPos. l'annullamento non influisce sullo stato del cursore o sulla posizione corrente del cursore.

Quando l'elenco SELECT della specifica di query associata al cursore contiene più riferimenti alla stessa colonna, se viene generato un errore o se il driver ignora i riferimenti duplicati ed esegue le operazioni richieste è definito dal driver.

Esecuzione di operazioni bulk

Se l'argomento RowNumber è 0, il driver esegue l'operazione specificata nell'argomento Operation per ogni riga del set di righe con valore SQL_ROW_PROCEED nel relativo campo nella matrice dell'operazione di riga a cui punta l'attributo di istruzione SQL_ATTR_ROW_OPERATION_PTR. Si tratta di un valore valido dell'argomento RowNumber per un argomento Operation di SQL_DELETE, SQL_REFRESH o SQL_UPDATE, ma non SQL_POSITION. SQLSetPos con un'operazione di SQL_POSITION e rowNumber uguale a 0 restituirà SQLSTATE HY109 (posizione del cursore non valida).

Se si verifica un errore che riguarda l'intero set di righe, ad esempio SQLSTATE HYT00 (Timeout scaduto), il driver restituisce SQL_ERROR e l'istruzione SQLSTATE appropriata. Il contenuto dei buffer del set di righe non è definito e la posizione del cursore rimane invariata.

Se si verifica un errore relativo a una singola riga, il driver:

  • Imposta l'elemento per la riga nella matrice di stato della riga a cui punta l'attributo SQL_ATTR_ROW_STATUS_PTR'istruzione su SQL_ROW_ERROR.

  • Invia uno o più SQLSTATEs aggiuntivi per l'errore nella coda degli errori e imposta il campo SQL_DIAG_ROW_NUMBER nella struttura dei dati di diagnostica.

Dopo aver elaborato l'errore o l'avviso, se il driver completa l'operazione per le righe rimanenti nel set di righe, restituisce SQL_SUCCESS_WITH_INFO. Pertanto, per ogni riga che ha restituito un errore, la coda degli errori contiene zero o più SQLSTATEs aggiuntivi. Se il driver arresta l'operazione dopo aver elaborato l'errore o l'avviso, restituisce SQL_ERROR.

Se il driver restituisce avvisi, ad esempio SQLSTATE 01004 (dati troncati), restituisce avvisi che si applicano all'intero set di righe o a righe sconosciute nel set di righe prima che restituisca le informazioni sull'errore applicabili a righe specifiche. Vengono restituiti avvisi per righe specifiche insieme a eventuali altre informazioni sull'errore relative a tali righe.

Se RowNumber è uguale a 0 e Operation è SQL_UPDATE, SQL_REFRESH o SQL_DELETE, il numero di righe su cui opera SQLSetPos è puntato dall'attributo dell'istruzione SQL_ATTR_ROWS_FETCHED_PTR.

Se RowNumber è uguale a 0 e Operation è SQL_DELETE, SQL_REFRESH o SQL_UPDATE, la riga corrente dopo l'operazione è la stessa della riga corrente prima dell'operazione.

Ignorare una riga in un'operazione bulk

La matrice di operazioni di riga può essere utilizzata per indicare che una riga nel set di righe corrente deve essere ignorata durante un'operazione bulk tramite SQLSetPos. Per fare in modo che il driver ignori una o più righe durante un'operazione bulk, un'applicazione deve eseguire la procedura seguente:

  1. Chiamare SQLSetStmtAttr per impostare l'SQL_ATTR_ROW_OPERATION_PTR dell'istruzione in modo che punti a una matrice di SQLUSMALLINTs. Questo campo può essere impostato anche chiamando SQLSetDescField per impostare il campo di intestazione SQL_DESC_ARRAY_STATUS_PTR dell'ARD, che richiede che un'applicazione osezioni l'handle del descrittore.

  2. Impostare ogni elemento della matrice di operazioni di riga su uno dei due valori seguenti:

    • SQL_ROW_IGNORE, per indicare che la riga è esclusa per l'operazione bulk.

    • SQL_ROW_PROCEED, per indicare che la riga è inclusa nell'operazione bulk. Si tratta del valore predefinito.

  3. Chiamare SQLSetPos per eseguire l'operazione bulk.

Le regole seguenti si applicano alla matrice di operazioni di riga:

  • SQL_ROW_IGNORE e SQL_ROW_PROCEED influiscono solo sulle operazioni bulk che usano SQLSetPos con un'operazione di SQL_DELETE o SQL_UPDATE. Non influiscono sulle chiamate a SQLSetPos con un'operazione di SQL_REFRESH o SQL_POSITION.

  • Il puntatore è impostato su Null per impostazione predefinita.

  • Se il puntatore è Null, tutte le righe vengono aggiornate come se tutti gli elementi fossero impostati su SQL_ROW_PROCEED.

  • L'impostazione di un SQL_ROW_PROCEED non garantisce che l'operazione si verifichi in quella riga specifica. Ad esempio, se una determinata riga del set di righe ha lo stato SQL_ROW_ERROR, il driver potrebbe non essere in grado di aggiornare tale riga indipendentemente dal fatto che l'applicazione abbia specificato SQL_ROW_PROCEED. Un'applicazione deve sempre controllare la matrice di stato della riga per verificare se l'operazione è stata completata correttamente.

  • SQL_ROW_PROCEED definito come 0 nel file di intestazione. Un'applicazione può inizializzare la matrice dell'operazione di riga su 0 per elaborare tutte le righe.

  • Se il numero di elemento "n" nella matrice di operazioni di riga è impostato su SQL_ROW_IGNORE e viene chiamato SQLSetPos per eseguire un'operazione di aggiornamento o eliminazione bulk, l'esima riga nel set di righe rimane invariata dopo la chiamata a SQLSetPos.

  • Un'applicazione deve impostare automaticamente una colonna di sola lettura su SQL_ROW_IGNORE.

Ignorare una colonna in un'operazione bulk

Per evitare la diagnostica di elaborazione non necessaria generata da tentativi di aggiornamento a una o più colonne di sola lettura, un'applicazione può impostare il valore nel buffer di lunghezza/indicatore associato su SQL_COLUMN_IGNORE. Per altre informazioni, vedere SQLBindCol.

Esempio di codice

Nell'esempio seguente un'applicazione consente a un utente di esplorare la tabella ORDERS e aggiornare lo stato dell'ordine. Il cursore è basato su keyset con dimensioni del set di righe di 20 e usa il controllo della concorrenza ottimistica confrontando le versioni delle righe. Dopo il recupero di ogni set di righe, l'applicazione lo stampa e consente all'utente di selezionare e aggiornare lo stato di un ordine. L'applicazione usa SQLSetPos per posizionare il cursore sulla riga selezionata ed esegue un aggiornamento posizionato della riga. Per maggiore chiarezza, la gestione degli errori viene omessa.

#define ROWS 20  
#define STATUS_LEN 6  
  
SQLCHAR        szStatus[ROWS][STATUS_LEN], szReply[3];  
SQLINTEGER     cbStatus[ROWS], cbOrderID;  
SQLUSMALLINT   rgfRowStatus[ROWS];  
SQLUINTEGER    sOrderID, crow = ROWS, irow;  
SQLHSTMT       hstmtS, hstmtU;  
  
SQLSetStmtAttr(hstmtS, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0);  
SQLSetStmtAttr(hstmtS, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_KEYSET_DRIVEN, 0);  
SQLSetStmtAttr(hstmtS, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWS, 0);  
SQLSetStmtAttr(hstmtS, SQL_ATTR_ROW_STATUS_PTR, (SQLPOINTER) rgfRowStatus, 0);  
SQLSetCursorName(hstmtS, "C1", SQL_NTS);  
SQLExecDirect(hstmtS, "SELECT ORDERID, STATUS FROM ORDERS ", SQL_NTS);  
  
SQLBindCol(hstmtS, 1, SQL_C_ULONG, &sOrderID, 0, &cbOrderID);  
SQLBindCol(hstmtS, 2, SQL_C_CHAR, szStatus, STATUS_LEN, &cbStatus);  
  
while ((retcode == SQLFetchScroll(hstmtS, SQL_FETCH_NEXT, 0)) != SQL_ERROR) {  
   if (retcode == SQL_NO_DATA_FOUND)  
      break;  
   for (irow = 0; irow < crow; irow++) {  
      if (rgfRowStatus[irow] != SQL_ROW_DELETED)  
         printf("%2d %5d %*s\n", irow+1, sOrderID, NAME_LEN-1, szStatus[irow]);  
   }  
   while (TRUE) {  
      printf("\nRow number to update?");  
      gets_s(szReply, 3);  
      irow = atoi(szReply);  
      if (irow > 0 && irow <= crow) {  
         printf("\nNew status?");  
         gets_s(szStatus[irow-1], (ROWS * STATUS_LEN));  
         SQLSetPos(hstmtS, irow, SQL_POSITION, SQL_LOCK_NO_CHANGE);  
         SQLPrepare(hstmtU,  
          "UPDATE ORDERS SET STATUS=? WHERE CURRENT OF C1", SQL_NTS);  
         SQLBindParameter(hstmtU, 1, SQL_PARAM_INPUT,  
            SQL_C_CHAR, SQL_CHAR,  
            STATUS_LEN, 0, szStatus[irow], 0, NULL);  
         SQLExecute(hstmtU);  
      } else if (irow == 0) {  
         break;  
      }  
   }  
}  

Per altri esempi, vedere Istruzioni Update ed Delete posizionate e Aggiornamento di righe nel set di righe con SQLSetPos.

Per informazioni su Vedere
Associazione di un buffer a una colonna in un set di risultati Funzione SQLBindCol
Esecuzione di operazioni bulk non correlate alla posizione del cursore a blocchi Funzione SQLBulkOperations
Annullamento dell'elaborazione dell'istruzione Funzione SQLCancel
Recupero di un blocco di dati o scorrimento di un set di risultati Funzione SQLFetchScroll
Recupero di un singolo campo di un descrittore Funzione SQLGetDescField
Recupero di più campi di un descrittore Funzione SQLGetDescRec
Impostazione di un singolo campo di un descrittore Funzione SQLSetDescField
Impostazione di più campi di un descrittore Funzione SQLSetDescRec
Impostazione di un attributo di istruzione Funzione SQLSetStmtAttr

Vedere anche

Informazioni di riferimento sulle API ODBC
File di intestazione ODBC