Funzione SQLSetPos
Conformità
Versione introdotta: Conformità agli standard ODBC 1.0: ODBC
Riepilogo
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 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 nel set di righe.
Per altre informazioni, vedere "Commenti".
Operazione
[Input] Operazione da eseguire:
SQL_POSITION SQL_REFRESH SQL_UPDATE SQL_DELETE
Nota
Il valore SQL_ADD per l'argomento Operation è stato deprecato per ODBC 3.x. I driver ODBC 3.x dovranno supportare SQL_ADD per garantire 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".
Valori restituiti
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 di SQL_HANDLE_STMT e handle di StatementHandle. La tabella seguente elenca i valori SQLSTATE comunemente restituiti da SQLSetPos e ne spiega ognuno nel contesto di questa funzione. La notazione "(DM)" precede le descrizioni di SQLSTATEs restituite da Gestione driver. Il codice restituito associato a ogni valore SQLSTATE è SQL_ERROR, a meno che non sia specificato diversamente.
Per tutti gli SQLSTATEs che possono restituire SQL_SUCCESS_WITH_INFO o SQL_ERROR (ad eccezione di 01xxx SQLSTATEs), SQL_SUCCESS_WITH_INFO viene restituito se si verifica un errore in una o più righe, ma non tutte, righe di un'operazione multirow e SQL_ERROR viene restituito 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 dell'operazione di cursore | L'argomento Operation è stato 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 del SQL_ATTR_SIMULATE_CURSOR Attributo in SQLSetStmtAttr.) (funzione restituisce SQL_SUCCESS_WITH_INFO.) L'argomento Operation è stato 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 è stato SQL_REFRESH e i dati stringa o binari restituiti per una colonna o colonne con un tipo di dati di SQL_C_CHAR o SQL_C_BINARY hanno generato il troncamento di dati binari non null o non NULL. |
01S01 | Errore nella riga | L'argomento RowNumber è 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 di un'operazione multirow e SQL_ERROR viene restituito se si verifica un errore in un'operazione a riga singola. (Questo 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 è stato SQL_REFRESH, il tipo di dati del buffer dell'applicazione non è stato 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 time, la parte frazionaria dell'ora è stata troncata. (La funzione restituisce SQL_SUCCESS_WITH_INFO. |
07006 | Violazione dell'attributo del tipo di dati con restrizioni | Impossibile 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 è stato SQL_REFRESH o SQL_UPDATE e una colonna è stata associata a un numero di colonna maggiore del numero di colonne nel set di risultati. |
21S02 | Il grado di tabella derivata non corrisponde all'elenco di colonne | L'argomento Operation è stato SQL_UPDATE e nessuna colonna era aggiornabile perché tutte le colonne non erano associate, di sola lettura o il valore nel buffer di lunghezza/indicatore associato era SQL_COLUMN_IGNORE. |
22001 | Dati stringa, troncamento destro | L'argomento Operation è stato SQL_UPDATE e l'assegnazione di un carattere o di un valore binario a una colonna ha comportato il troncamento di nonblank (per i caratteri) o non Null (per i caratteri binari) o byte. |
22003 | Valore numerico non compreso nell'intervallo | L'argomento Operation è stato SQL_UPDATE e l'assegnazione di un valore numerico a una colonna nel set di risultati ha causato il troncamento dell'intera parte (anziché frazionaria) del numero. L'argomento Operation è stato 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 è stato SQL_UPDATE e l'assegnazione di un valore di data o timestamp a una colonna nel set di risultati ha causato l'interruzione dell'intervallo del campo anno, mese o giorno. L'argomento Operation è stato SQL_REFRESH e la restituzione del valore di data o timestamp per una o più colonne associate avrebbe causato l'interruzione dell'intervallo del campo anno, mese o giorno. |
22008 | Overflow del campo data/ora | L'argomento Operation è stato SQL_UPDATE e le prestazioni dell'aritmetica datetime sui dati inviati a una colonna nel set di risultati hanno generato un campo datetime (anno, mese, giorno, ora, minuto o secondo) del risultato non compreso nell'intervallo consentito di valori per il campo oppure non valido in base alle regole naturali del calendario gregoriano per datetime. L'argomento Operation è stato SQL_REFRESH e le prestazioni dell'aritmetica datetime sui dati recuperati dal set di risultati hanno generato un campo datetime (l'anno, il mese, il giorno, l'ora, il minuto o il secondo campo) del risultato non compreso nell'intervallo consentito di valori per il campo oppure non è valido in base alle regole naturali del calendario gregoriano per datetimes. |
22015 | Overflow del campo intervallo | L'argomento Operation è stato SQL_UPDATE e l'assegnazione di un tipo C numerico o intervallo esatto a un tipo di dati SQL intervallo ha causato una perdita di cifre significative. L'argomento Operation è stato SQL_UPDATE. Quando si assegna a un tipo SQL di intervallo, non è presente alcuna rappresentazione del valore del tipo C nel tipo SQL intervallo. L'argomento Operation è stato SQL_REFRESH e l'assegnazione da un tipo SQL numerico o intervallo esatto a un tipo C intervallo ha causato una perdita di cifre significative nel campo iniziale. L'argomento Operation è stato SQL_ REFRESH. Quando si assegna a un tipo C intervallo, non è presente alcuna rappresentazione del valore del tipo SQL nel tipo C intervallo. |
22018 | Valore carattere non valido per la specifica del cast | L'argomento Operation era SQL_REFRESH, il tipo C era un tipo numerico esatto o approssimativo, un tipo di dati datetime o interval, il tipo SQL della colonna era un tipo di dati carattere e il valore nella colonna non era un valore letterale valido del tipo C associato. L'argomento Operation è stato SQL_UPDATE; il tipo SQL era un valore numerico esatto o approssimativo, un tipo di dati datetime o interval, il tipo C era SQL_C_CHAR e il valore nella colonna non era un valore letterale valido del tipo SQL associato. |
23000 | Violazione del vincolo di integrità | L'argomento Operation è stato SQL_DELETE o SQL_UPDATE e un vincolo di integrità è stato violato. |
24000 | Stato del cursore non valido | StatementHandle era in uno stato eseguito, ma nessun set di risultati era associato a StatementHandle. (DM) Un cursore è stato aperto in StatementHandle, ma SQLFetch o SQLFetchScroll non è stato chiamato. È stato aperto un cursore in StatementHandle e SQLFetch o SQLFetchScroll è stato chiamato, ma il cursore è stato posizionato prima dell'inizio del set di risultati o dopo la fine del set di risultati. L'argomento Operation è stato 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 della risorsa con un'altra transazione. |
40003 | Completamento istruzione 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 Operazione. Il driver non è riuscito a bloccare la riga come richiesto nell'argomento LockType. |
44000 | Violazione della clausola WITH CHECK OPTION | L'argomento Operation è stato 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 saranno più presenti nella tabella visualizzata. |
HY000 | Errore generale: | Si è verificato un errore per il quale non è stato specificato SQLSTATE e per il quale non è stato definito alcun 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 memoria necessaria per supportare l'esecuzione o il completamento della funzione. |
HY008 | Operazione annullata | L'elaborazione asincrona è stata abilitata per StatementHandle. La funzione è stata chiamata e prima di completare l'esecuzione, SQLCancel o SQLCancelHandle è stata chiamata su StatementHandle e quindi la funzione è stata chiamata nuovamente in StatementHandle. La funzione è stata chiamata e prima del completamento dell'esecuzione, SQLCancel o SQLCancelHandle è stato chiamato su StatementHandle da un thread diverso in un'applicazione multithread. |
HY010 | Errore della sequenza di funzioni | (DM) È stata chiamata una funzione in esecuzione asincrona per l'handle di connessione associato a StatementHandle. Questa funzione asincrona era ancora in esecuzione quando è stata chiamata la funzione SQLSetPos. (DM) StatementHandle specificato non era in uno stato eseguito. La funzione è stata chiamata senza prima chiamare SQLExecDirect, SQLExecute o una funzione di catalogo. (DM) Una funzione in esecuzione asincrona (non questa) è stata chiamata per StatementHandle ed è ancora in esecuzione quando questa funzione è stata chiamata. (DM) SQLExecute, SQLExecDirect, SQLBulkOperations o SQLSetPos è stato chiamato per StatementHandle e restituito 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 e SQLSetPos è stato chiamato per un StatementHandle dopo la chiamata a SQLFetch. |
HY011 | Impossibile impostare l'attributo ora | (DM) Il driver era un driver ODBC 2.x , l'attributo dell'istruzione SQL_ATTR_ROW_STATUS_PTR è stato impostato, quindi è stato chiamato SQLSetPos prima della chiamata a SQLFetch, SQLFetchScroll o SQLExtendedFetch . |
HY013 | Errore di gestione della memoria | Impossibile 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 della stringa o del buffer non valida | L'argomento Operation è stato SQL_UPDATE, un valore di dati era un puntatore Null e il valore della lunghezza della colonna non era 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 era SQL_UPDATE, un valore di dati non era un puntatore Null, il tipo di dati C era SQL_C_BINARY o SQL_C_CHAR e il valore della lunghezza della colonna era minore di 0 ma non uguale a SQL_DATA_AT_EXEC, SQL_COLUMN_IGNORE, SQL_NTS o SQL_NULL_DATA o minore o uguale a SQL_LEN_DATA_AT_EXEC_OFFSET. Il valore in un buffer di lunghezza/indicatore è stato SQL_DATA_AT_EXEC; il tipo SQL era SQL_LONGVARCHAR, SQL_LONGVARBINARY o un tipo di dati lungo specifico dell'origine dati; e il tipo di informazioni SQL_NEED_LONG_DATA_LEN in SQLGetInfo era "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 è stato 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'attributo SQL_ATTR_CURSOR_TYPE in SQLSetStmtAttr. L'argomento Operation è stato SQL_UPDATE, SQL_DELETE o SQL_REFRESH e la riga identificata dall'argomento RowNumber è stata eliminata o non è stata recuperata. (DM) L'argomento RowNumber era 0 e l'argomento Operation era SQL_POSITION. SQLSetPos è stato chiamato dopo la chiamata di SQLBulkOperations e prima della chiamata di SQLFetchScroll o SQLFetch . |
HY117 | La connessione viene sospesa a causa dello stato sconosciuto della transazione. Sono consentite solo funzioni disconnesse 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 nell'argomento LockType . |
HYT00 | Timeout scaduto | Periodo di timeout della query scaduto prima che l'origine dati restituisca il set di risultati. Il periodo di timeout viene impostato tramite SQLSetStmtAttr con un attributo di SQL_ATTR_QUERY_TIMEOUT. |
HYT01 | Il timeout della connessione è scaduto | Periodo di timeout della connessione scaduto prima che l'origine dati rispondesse 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 sull'istruzione indica che è possibile chiamare SQLSetPos e le operazioni da eseguire per garantire la compatibilità con le applicazioni ODBC 2.x , vedere Cursori a blocchi, cursori scorrevoli 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 nel 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 basate su 0 e l'argomento RowNumber è basato su 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 matrice 4, ma specifica un valore RowNumber pari a 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.
Chiamate a SQLGetData.
Chiamate a SQLSetPos con le opzioni di SQL_DELETE, SQL_REFRESH e SQL_UPDATE.
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 di 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 dell'istruzione SQL_ATTR_ROW_OPERATION_PTR viene ignorato per l'operazione 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 a livello di riga e di 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 recuperati, l'appartenenza al set di righe è fissa. Questo comportamento è 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 di riga di SQL_ROW_DELETED. Le righe eliminate all'interno del set di righe continueranno a essere contrassegnate come eliminate fino al recupero successivo. Le righe scompariranno al successivo recupero se il cursore supporta la compressione (in cui un SQLFetch o SQLFetchScroll successivo non restituisce righe eliminate). Le righe aggiunte non vengono visualizzate quando viene eseguito un aggiornamento con SQLSetPos . Questo comportamento è diverso da SQLFetchScroll con fetchType di SQL_FETCH_RELATIVE e RowNumber uguale a 0, che aggiorna anche il set di righe corrente, ma mostrerà record aggiunti o record eliminati se queste operazioni sono supportate dal cursore. Un aggiornamento riuscito con SQLSetPos modifica lo stato di riga di SQL_ROW_ADDED in SQL_ROW_SUCCESS (se la matrice di stato della riga esiste). Un aggiornamento riuscito con SQLSetPos modificherà lo stato di riga di 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 in 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 usati per garantire che la concorrenza del cursore venga aggiornata 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 dell'istruzione SQL_ATTR_ROW_OPERATION_PTR viene ignorato per l'operazione SQL_REFRESH. |
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 (l'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). È definito dal driver il comportamento se SQLSetPos con un argomento Operation di SQL_UPDATE viene chiamato su un cursore che contiene colonne duplicate. Il driver può restituire un'istruzione SQLSTATE definita dal driver, può aggiornare la prima colonna visualizzata nel set di risultati o eseguire altri comportamenti definiti dal driver. È possibile utilizzare la matrice di operazioni di riga a cui punta l'attributo di istruzione SQL_ATTR_ROW_OPERATION_PTR per indicare che una riga nel set di righe corrente deve essere ignorata durante un aggiornamento bulk. Per altre informazioni, vedere "Status and Operation Arrays" più avanti in questa guida di 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, le operazioni seguenti non sono valide per la riga: istruzioni di aggiornamento ed eliminazione posizionate, chiamate a SQLGetData e chiamate a SQLSetPos con Operation impostato su qualsiasi elemento tranne SQL_POSITION. Per i driver che supportano la compressione, la riga viene eliminata dal cursore quando vengono recuperati nuovi dati dall'origine dati. Se la riga rimane visibile dipende dal tipo di cursore. Ad esempio, le righe eliminate sono visibili ai cursori statici e basati su keyset, ma invisibili ai cursori dinamici. È possibile utilizzare la matrice di operazioni di riga a cui punta l'attributo di istruzione SQL_ATTR_ROW_OPERATION_PTR per indicare che una riga nel set di righe corrente deve essere ignorata durante un'eliminazione bulk. Per altre informazioni, vedere "Status and Operation Arrays" più avanti in questa guida di 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 livelli di concorrenza e 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 concede gli stessi privilegi a tutte le istruzioni sulla connessione. In particolare, un blocco acquisito da un'istruzione in una connessione può essere sbloccato da un'istruzione diversa nella stessa connessione.
Una riga bloccata tramite SQLSetPos rimane bloccata finché l'applicazione chiama SQLSetPos per la riga con LockType impostata su SQL_LOCK_UNLOCK oppure finché 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 nella connessione (se un cursore viene chiuso quando viene eseguito il commit o il rollback di una transazione, come indicato dal SQL_CURSOR_COMMIT_BEHAVIOR e SQL_CURSOR_ROLLBACK_BEHAVIOR tipi di informazioni 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 precedente alla chiamata di SQLSetPos . Questo valore di LockType consente alle origini dati che non supportano il blocco esplicito a livello di riga per usare qualsiasi blocco richiesto dai livelli di concorrenza e isolamento delle transazioni correnti. |
SQL_LOCK_EXCLUSIVE | Il driver o l'origine dati blocca la riga esclusivamente. Non è possibile utilizzare un'istruzione in una connessione diversa o in un'applicazione diversa per acquisire blocchi nella 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 finché 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 commit o al 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 venga modificata 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 abbia esito positivo solo se l'applicazione specificata 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 di istruzione SQL_ATTR_CONCURRENCY, il driver confronta le versioni di riga o i valori e rifiuta l'operazione se la riga è stata modificata dopo il recupero della riga dall'applicazione.
Se l'applicazione specifica SQL_CONCUR_READ_ONLY per l'attributo dell'istruzione SQL_ATTR_CONCURRENCY, il driver rifiuta qualsiasi operazione di aggiornamento o eliminazione.
Per altre informazioni sull'attributo dell'istruzione SQL_ATTR_CONCURRENCY, vedere SQLSetStmtAttr.
Matrice di stato e operazioni
Quando si chiama SQLSetPos vengono usati gli array di stato e operazioni seguenti:
La matrice di stato della riga, a cui punta il campo SQL_DESC_ARRAY_STATUS_PTR nell'attributo di istruzione IRD e 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 punta all'attributo dell'istruzione SQL_ATTR_ROW_STATUS_PTR.
La matrice di operazioni di riga, a cui punta il campo SQL_DESC_ARRAY_STATUS_PTR nel ARD e l'attributo dell'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 della matrice è impostato su SQL_ROW_PROCEED (impostazione predefinita) o SQL_ROW_IGNORE. Questa matrice fa riferimento all'attributo di istruzione SQL_ATTR_ROW_OPERATION_PTR.
Il numero di elementi nelle matrici di stato e operazioni deve essere uguale al numero di righe nel set di righe, come definito dall'attributo dell'istruzione SQL_ATTR_ROW_ARRAY_SIZE.
Per informazioni sulla matrice di stato della riga, vedere SQLFetch. Per informazioni sulla matrice di operazioni 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:
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 buffer per i dati e la lunghezza della colonna.
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.
Chiamare SQLExecDirect, SQLExecute o una funzione di catalogo per creare un set di risultati.
Chiamare SQLFetch o SQLFetchScroll per recuperare i dati.
Per altre informazioni sull'uso di SQLSetPos, vedere Aggiornamento dei 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 dei 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. Vengono comunemente usati per inviare dati per SQL_LONGVARBINARY e SQL_LONGVARCHAR colonne e possono essere combinate con altre colonne.
Per aggiornare i dati con SQLSetPos, un'applicazione:
Inserisce i valori nei buffer di dati e lunghezza/indicatore associati a SQLBindCol:
Per le colonne normali, l'applicazione inserisce il nuovo valore di colonna nel buffer *TargetValuePtr e la lunghezza di tale valore nel buffer *StrLen_or_IndPtr . Se la riga non deve essere aggiornata, l'applicazione inserisce SQL_ROW_IGNORE nell'elemento della riga della matrice di operazioni 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(lunghezza) nel buffer *StrLen_or_IndPtr . Se il tipo di dati SQL della colonna è SQL_LONGVARBINARY, SQL_LONGVARCHAR o un tipo di dati specifico dell'origine dati long e il driver restituisce "Y" per il tipo di informazioni SQL_NEED_LONG_DATA_LEN in SQLGetInfo, la lunghezza è il numero di byte di dati da inviare per il parametro; in caso contrario, deve essere un valore non negativo e viene ignorato.
Chiama SQLSetPos con l'argomento Operation impostato su SQL_UPDATE per aggiornare la riga di dati.
Se non sono presenti colonne di dati in fase di esecuzione, il processo viene completato.
Se sono presenti colonne data-at-execution, la funzione restituisce SQL_NEED_DATA e procede al passaggio 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 ognuno di essi.
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 descrittori con SQLSetDescRec. Il valore restituito da SQLParamData è un valore a 32 bit passato a SQLBindParameter nell'argomento ParameterValuePtr .
Nota
Le colonne data-at-execution sono colonne in 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 in fase di elaborazione.
Chiama SQLPutData una o più volte per inviare dati per la colonna. È necessaria più di una chiamata se non è possibile restituire tutti i valori di dati nel buffer *TargetValuePtr specificato in SQLPutData. Sono consentite più chiamate a SQLPutData per la stessa colonna solo quando si inviano dati C carattere a una colonna con un tipo di dati carattere, binario o specifico dell'origine dati o quando si inviano dati C binari a una colonna con un carattere, tipo di dati binario o specifico dell'origine dati.
Chiama di nuovo 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 di dati in fase di esecuzione, il processo viene completato. 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 affinché la riga appropriata venga 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 dell'invio dei dati 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 data-at-execution, il driver annulla l'operazione. L'applicazione può quindi chiamare di nuovo 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 di operazioni di riga a cui punta SQL_ATTR_ROW_OPERATION_PTR attributo di istruzione. 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 un valore RowNumber uguale a 0 restituirà SQLSTATE HY109 (posizione del cursore non valida).
Se si verifica un errore relativo all'intero set di righe, ad esempio SQLSTATE HYT00 (timeout scaduto), il driver restituisce SQL_ERROR e l'istanza di 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 dell'istruzione SQL_ATTR_ROW_STATUS_PTR su SQL_ROW_ERROR.
Inserisce 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 di errori contiene zero o più STATI SQL aggiuntivi. Se il driver arresta l'operazione dopo l'elaborazione dell'errore o dell'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 di restituire le informazioni sull'errore applicabili a righe specifiche. Restituisce 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 viene 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 è uguale alla 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 indirizzare il driver a ignorare una o più righe durante un'operazione bulk, un'applicazione deve seguire questa procedura:
Chiamare SQLSetStmtAttr per impostare l'attributo dell'istruzione SQL_ATTR_ROW_OPERATION_PTR in modo che punti a una matrice di SQLUSMALLINTs. Questo campo può anche essere impostato chiamando SQLSetDescField per impostare il campo intestazione SQL_DESC_ARRAY_STATUS_PTR del ARD, che richiede che un'applicazione ottenga l'handle del descrittore.
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.
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 usando 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 elemento su SQL_ROW_PROCEED non garantisce che l'operazione venga eseguita in tale riga specifica. Ad esempio, se una determinata riga nel 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 specificata SQL_ROW_PROCEED. Un'applicazione deve sempre controllare la matrice di stato della riga per verificare se l'operazione ha avuto esito positivo.
SQL_ROW_PROCEED è definito come 0 nel file di intestazione. Un'applicazione può inizializzare la matrice di operazioni 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 SQLSetPos viene chiamato per eseguire un'operazione di aggiornamento o eliminazione bulk, la na 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 l'elaborazione non necessaria della diagnostica generata dai 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 pari a 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. La gestione degli errori viene omessa per maggiore chiarezza.
#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 di aggiornamento ed eliminazione posizionate e aggiornamento di righe nel set di righe con SQLSetPos.
Funzioni correlate
Per informazioni su | Vedere |
---|---|
Associazione di un buffer a una colonna in un set di risultati | Funzione SQLBindCol |
Esecuzione di operazioni bulk che non sono correlate alla posizione del cursore del blocco | Funzione SQLBulkOperations |
Annullamento dell'elaborazione delle istruzioni | 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 |