Funzione SQLBindCol
Conformità
Versione introdotta: Conformità agli standard ODBC 1.0: ISO 92
Riepilogo
SQLBindCol associa i buffer dei dati dell'applicazione alle colonne nel set di risultati.
Sintassi
SQLRETURN SQLBindCol(
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLSMALLINT TargetType,
SQLPOINTER TargetValuePtr,
SQLLEN BufferLength,
SQLLEN * StrLen_or_IndPtr);
Argomenti
StatementHandle
[Input] Handle di istruzione.
ColumnNumber
[Input] Numero della colonna del set di risultati da associare. Le colonne vengono numerate in ordine crescente a partire da 0, dove la colonna 0 è la colonna del segnalibro. Se i segnalibri non vengono usati, ovvero l'attributo dell'istruzione SQL_ATTR_USE_BOOKMARKS è impostato su SQL_UB_OFF, i numeri di colonna iniziano da 1.
TargetType
[Input] Identificatore del tipo di dati C del buffer *TargetValuePtr . Quando recupera dati dall'origine dati con SQLFetch, SQLFetchScroll, SQLBulkOperations o SQLSetPos, il driver converte i dati in questo tipo; quando invia dati all'origine dati con SQLBulkOperations o SQLSetPos, il driver converte i dati da questo tipo. Per un elenco di tipi di dati E identificatori di tipo C validi, vedere la sezione Tipi di dati C nell'Appendice D: Tipi di dati.
Se l'argomento TargetType è un tipo di dati interval, per i dati vengono utilizzati rispettivamente il valore predefinito di precisione iniziale intervallo (2) e la precisione predefinita dei secondi di intervallo (6), come impostato nei campi SQL_DESC_DATETIME_INTERVAL_PRECISION e SQL_DESC_PRECISION della ARD. Se l'argomento TargetType è SQL_C_NUMERIC, la precisione predefinita (definita dal driver) e la scala predefinita (0), come impostato nei campi SQL_DESC_PRECISION e SQL_DESC_SCALE della ARD, vengono utilizzati per i dati. Se una precisione o una scala predefinita non è appropriata, l'applicazione deve impostare in modo esplicito il campo descrittore appropriato tramite una chiamata a SQLSetDescField o SQLSetDescRec.
È anche possibile specificare un tipo di dati C esteso. Per altre informazioni, vedere Tipi di dati C in ODBC.
TargetValuePtr
[Input/Output posticipato] Puntatore al buffer di dati da associare alla colonna. SQLFetch e SQLFetchScroll restituiscono dati in questo buffer. SQLBulkOperations restituisce dati in questo buffer quando Operation è SQL_FETCH_BY_BOOKMARK; recupera i dati da questo buffer quando Operation è SQL_ADD o SQL_UPDATE_BY_BOOKMARK. SQLSetPos restituisce dati in questo buffer quando Operation è SQL_REFRESH; recupera i dati da questo buffer quando Operation è SQL_UPDATE.
Se TargetValuePtr è un puntatore Null, il driver annulla l'associazione del buffer di dati per la colonna. Un'applicazione può annullare l'associazione di tutte le colonne chiamando SQLFreeStmt con l'opzione SQL_UNBIND. Un'applicazione può annullare l'associazione del buffer di dati per una colonna ma ha ancora un buffer di lunghezza/indicatore associato per la colonna, se l'argomento TargetValuePtr nella chiamata a SQLBindCol è un puntatore Null, ma l'argomento StrLen_or_IndPtr è un valore valido.
BufferLength
[Input] Lunghezza del buffer *TargetValuePtr in byte.
Il driver usa BufferLength per evitare di scrivere oltre la fine del buffer *TargetValuePtr quando restituisce dati a lunghezza variabile, ad esempio dati di tipo carattere o binario. Si noti che il driver conta il carattere di terminazione Null quando restituisce dati di tipo carattere a *TargetValuePtr. *TargetValuePtr deve pertanto contenere spazio per il carattere di terminazione Null oppure il driver tronca i dati.
Quando il driver restituisce dati a lunghezza fissa, ad esempio un numero intero o una struttura di data, il driver ignora BufferLength e presuppone che il buffer sia sufficientemente grande da contenere i dati. Pertanto, è importante che l'applicazione alloca un buffer sufficientemente grande per i dati a lunghezza fissa o il driver scriverà oltre la fine del buffer.
SQLBindCol restituisce SQLSTATE HY090 (stringa o lunghezza buffer non valida) quando BufferLength è minore di 0, ma non quando BufferLength è 0. Tuttavia, se TargetType specifica un tipo di carattere, un'applicazione non deve impostare BufferLength su 0, perché i driver conformi all'interfaccia della riga di comando ISO restituiscono SQLSTATE HY090 (stringa o lunghezza buffer non valida) in tal caso.
StrLen_or_IndPtr
[Input/Output posticipato] Puntatore al buffer di lunghezza/indicatore da associare alla colonna. SQLFetch e SQLFetchScroll restituiscono un valore in questo buffer. SQLBulkOperations recupera un valore da questo buffer quando Operation è SQL_ADD, SQL_UPDATE_BY_BOOKMARK o SQL_DELETE_BY_BOOKMARK. SQLBulkOperations restituisce un valore in questo buffer quando Operation è SQL_FETCH_BY_BOOKMARK. SQLSetPos restituisce un valore in questo buffer quando Operation è SQL_REFRESH; recupera un valore da questo buffer quando Operation è SQL_UPDATE.
SQLFetch, SQLFetchScroll, SQLBulkOperations e SQLSetPos possono restituire i valori seguenti nel buffer di lunghezza/indicatore:
Lunghezza dei dati disponibili per la restituzione
SQL_NO_TOTAL
SQL_NULL_DATA
L'applicazione può inserire i valori seguenti nel buffer di lunghezza/indicatore da usare con SQLBulkOperations o SQLSetPos:
Lunghezza dei dati inviati
SQL_NTS
SQL_NULL_DATA
SQL_DATA_AT_EXEC
Risultato della macro SQL_LEN_DATA_AT_EXEC
SQL_COLUMN_IGNORE
Se il buffer indicatore e il buffer di lunghezza sono buffer separati, il buffer indicatore può restituire solo SQL_NULL_DATA, mentre il buffer di lunghezza può restituire tutti gli altri valori.
Per altre informazioni, vedere Funzione SQLBulkOperations, funzione SQLFetch, funzione SQLSetPos e Uso di valori length/indicatore.
Se StrLen_or_IndPtr è un puntatore Null, non viene usato alcun valore di lunghezza o indicatore. Si tratta di un errore durante il recupero dei dati e i dati sono NULL.
Vedere INFORMAZIONI SU ODBC a 64 bit, se l'applicazione verrà eseguita in un sistema operativo a 64 bit.
Resi
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR o SQL_INVALID_HANDLE.
Diagnostica
Quando SQLBindCol restituisce SQL_ERROR o SQL_SUCCESS_WITH_INFO, è possibile ottenere un valore SQLSTATE associato chiamando SQLGetDiagRec con handleTypedi SQL_HANDLE_STMT e handle di StatementHandle. La tabella seguente elenca i valori SQLSTATE restituiti in genere da SQLBindCol 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.
SQLSTATE | Errore | Descrizione |
---|---|---|
01000 | Avviso generale | Messaggio informativo specifico del driver. (La funzione restituisce SQL_SUCCESS_WITH_INFO. |
07006 | Violazione dell'attributo del tipo di dati con restrizioni | (DM) L'argomento ColumnNumber era 0 e l'argomento TargetType non era SQL_C_BOOKMARK o SQL_C_VARBOOKMARK. |
07009 | Indice descrittore non valido | Il valore specificato per l'argomento ColumnNumber ha superato il numero massimo di colonne nel set di risultati. |
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. |
HY003 | Tipo di buffer dell'applicazione non valido | L'argomento TargetType non era né un tipo di dati valido né SQL_C_DEFAULT. |
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 è stato chiamato SQLBindCol . (DM) SQLExecute, SQLExecDirect o SQLMoreResults è stato chiamato per StatementHandle e restituito SQL_PARAM_DATA_AVAILABLE. Questa funzione è stata chiamata prima del recupero dei dati per tutti i parametri trasmessi. (DM) È stata chiamata una funzione in esecuzione asincrona per StatementHandle ed era 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. |
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 | (DM) Il valore specificato per l'argomento BufferLength è minore di 0. (DM) Il driver era ODBC 2.X driver, l'argomento ColumnNumber è stato impostato su 0 e il valore specificato per l'argomento BufferLength non è uguale a 4. |
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 la conversione specificata dalla combinazione dell'argomento TargetType e del tipo di dati SQL specifico del driver della colonna corrispondente. L'argomento ColumnNumber era 0 e il driver non supporta i segnalibri. Il driver supporta solo ODBC 2.x e l'argomento TargetType è uno dei seguenti: SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT e uno qualsiasi dei tipi di dati C intervallo elencati in Tipi di dati C nell'Appendice D: Tipi di dati. Il driver supporta solo le versioni ODBC precedenti alla 3.50 e l'argomento TargetType è stato SQL_C_GUID. |
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. |
Commenti
SQLBindCol viene usato per associare o associare colonne nel set di risultati a buffer di dati e buffer di lunghezza/indicatore nell'applicazione. Quando l'applicazione chiama SQLFetch, SQLFetchScroll o SQLSetPos per recuperare i dati, il driver restituisce i dati per le colonne associate nei buffer specificati. Per altre informazioni, vedere Funzione SQLFetch. Quando l'applicazione chiama SQLBulkOperations per aggiornare o inserire una riga o SQLSetPos per aggiornare una riga, il driver recupera i dati per le colonne associate dai buffer specificati. Per altre informazioni, vedere Funzione SQLBulkOperations o funzione SQLSetPos. Per altre informazioni sull'associazione, vedere Recupero dei risultati (Basic).For more information about binding, see Retrieving Results (Basic).
Si noti che le colonne non devono essere associate per recuperare i dati da essi. Un'applicazione può anche chiamare SQLGetData per recuperare i dati dalle colonne. Sebbene sia possibile associare alcune colonne in una riga e chiamare SQLGetData per altre, questa operazione è soggetta ad alcune restrizioni. Per altre informazioni, vedere SQLGetData.
Binding, unbinding e ribinding di colonne
Una colonna può essere associata, non associata o rebound in qualsiasi momento, anche dopo che i dati sono stati recuperati dal set di risultati. La nuova associazione diventa effettiva alla successiva chiamata di una funzione che usa associazioni. Si supponga, ad esempio, che un'applicazione associa le colonne in un set di risultati e chiami SQLFetch. Il driver restituisce i dati nei buffer associati. Si supponga ora che l'applicazione associa le colonne a un set diverso di buffer. Il driver non inserisce i dati per la riga appena recuperata nei buffer appena associati. Attende invece che SQLFetch venga chiamato di nuovo e quindi inserisce i dati per la riga successiva nei buffer appena associati.
Nota
L'attributo di istruzione SQL_ATTR_USE_BOOKMARKS deve essere sempre impostato prima di eseguire l'associazione di una colonna alla colonna 0. Questo non è obbligatorio, ma è fortemente consigliato.
Associazione di colonne
Per associare una colonna, un'applicazione chiama SQLBindCol e passa il numero di colonna, il tipo, l'indirizzo e la lunghezza di un buffer di dati e l'indirizzo di un buffer di lunghezza/indicatore. Per informazioni sull'uso di questi indirizzi, vedere "Indirizzi buffer" più avanti in questa sezione. Per altre informazioni sull'associazione di colonne, vedere Uso di SQLBindCol.
L'uso di questi buffer è posticipato; ovvero, l'applicazione le associa in SQLBindCol , ma il driver accede da altre funzioni, vale a dire SQLBulkOperations, SQLFetch, SQLFetchScroll o SQLSetPos. È responsabilità dell'applicazione assicurarsi che i puntatori specificati in SQLBindCol rimangano validi finché l'associazione rimane attiva. Se l'applicazione consente a questi puntatori di diventare non validi, ad esempio libera un buffer, e quindi chiama una funzione che prevede che siano valide, le conseguenze non sono indefinite. Per altre informazioni, vedere Buffer posticipati.
L'associazione rimane attiva fino a quando non viene sostituita da una nuova associazione, la colonna non è associato o l'istruzione viene liberata.
Annullamento dell'associazione di colonne
Per annullare l'associazione di una singola colonna, un'applicazione chiama SQLBindCol con ColumnNumber impostato sul numero di tale colonna e TargetValuePtr impostato su un puntatore Null. Se ColumnNumber fa riferimento a una colonna non associato, SQLBindCol restituisce comunque SQL_SUCCESS.
Per annullare l'associazione di tutte le colonne, un'applicazione chiama SQLFreeStmt con fOption impostato su SQL_UNBIND. Questa operazione può essere eseguita impostando il campo SQL_DESC_COUNT della ARD su zero.
Ribinding di colonne
Un'applicazione può eseguire una delle due operazioni per modificare un'associazione:
Chiamare SQLBindCol per specificare una nuova associazione per una colonna già associata. Il driver sovrascrive l'associazione precedente con quella nuova.
Specificare un offset da aggiungere all'indirizzo del buffer specificato dalla chiamata di associazione a SQLBindCol. Per altre informazioni, vedere la sezione successiva"Binding Offsets".
Offset di associazione
Un offset di associazione è un valore aggiunto agli indirizzi dei buffer di dati e lunghezza/indicatore (come specificato nell'argomento TargetValuePtr e StrLen_or_IndPtr ) prima che vengano dereferenziati. Quando vengono usati gli offset, le associazioni sono un "modello" della disposizione dei buffer dell'applicazione e l'applicazione può spostare questo "modello" in diverse aree di memoria modificando l'offset. Poiché lo stesso offset viene aggiunto a ogni indirizzo in ogni associazione, gli offset relativi tra buffer per colonne diverse devono essere uguali all'interno di ogni set di buffer. Questo vale sempre quando viene usata l'associazione a livello di riga; L'applicazione deve disporre attentamente i buffer affinché questo sia true quando viene utilizzata l'associazione a livello di colonna.
L'uso di un offset di associazione ha fondamentalmente lo stesso effetto della riassociazione di una colonna chiamando SQLBindCol. La differenza è che una nuova chiamata a SQLBindCol specifica nuovi indirizzi per il buffer di dati e il buffer di lunghezza/indicatore, mentre l'uso di un offset di associazione non modifica gli indirizzi, ma aggiunge semplicemente un offset. L'applicazione può specificare un nuovo offset ogni volta che lo desidera e questo offset viene sempre aggiunto agli indirizzi associati originariamente. In particolare, se l'offset è impostato su 0 o se l'attributo dell'istruzione è impostato su un puntatore Null, il driver usa gli indirizzi associati originariamente.
Per specificare un offset di associazione, l'applicazione imposta l'attributo dell'istruzione SQL_ATTR_ROW_BIND_OFFSET_PTR sull'indirizzo di un buffer SQLINTEGER. Prima che l'applicazione chiami una funzione che usa associazioni, inserisce un offset in byte in questo buffer. Per determinare l'indirizzo del buffer da usare, il driver aggiunge l'offset all'indirizzo nell'associazione. La somma dell'indirizzo e dell'offset deve essere un indirizzo valido, ma l'indirizzo a cui viene aggiunto l'offset non deve essere valido. Per altre informazioni sull'uso degli offset di associazione, vedere "Indirizzi buffer" più avanti in questa sezione.
Matrici di binding
Se la dimensione del set di righe (il valore dell'attributo dell'istruzione SQL_ATTR_ROW_ARRAY_SIZE) è maggiore di 1, l'applicazione associa matrici di buffer anziché buffer singoli. Per altre informazioni, vedere Cursori a blocchi.
L'applicazione può associare matrici in due modi:
Associare una matrice a ogni colonna. Questa operazione viene definita associazione a livello di colonna perché ogni struttura di dati (matrice) contiene dati per una singola colonna.
Definire una struttura per contenere i dati per un'intera riga e associare una matrice di queste strutture. Questa operazione viene definita associazione a livello di riga perché ogni struttura di dati contiene i dati per una singola riga.
Ogni matrice di buffer deve avere almeno il numero di elementi di dimensioni del set di righe.
Nota
Un'applicazione deve verificare che l'allineamento sia valido. Per altre informazioni sulle considerazioni sull'allineamento, vedere Allineamento.
Associazione per colonna
Nell'associazione a colonne, l'applicazione associa matrici di dati e lunghezza/indicatore separate a ogni colonna.
Per usare l'associazione a livello di colonna, l'applicazione imposta innanzitutto l'attributo dell'istruzione SQL_ATTR_ROW_BIND_TYPE su SQL_BIND_BY_COLUMN. Questa è l'impostazione predefinita. Per associare ogni colonna, l'applicazione esegue i passaggi seguenti:
Alloca una matrice di buffer di dati.
Alloca una matrice di buffer di lunghezza/indicatore.
Nota
Se l'applicazione scrive direttamente nei descrittori quando viene usata l'associazione a livello di colonna, è possibile usare matrici separate per i dati di lunghezza e indicatore.
Chiama SQLBindCol con gli argomenti seguenti:
TargetType è il tipo di un singolo elemento nella matrice di buffer di dati.
TargetValuePtr è l'indirizzo della matrice di buffer di dati.
BufferLength è la dimensione di un singolo elemento nella matrice di buffer di dati. L'argomento BufferLength viene ignorato quando i dati sono a lunghezza fissa.
StrLen_or_IndPtr è l'indirizzo della matrice di lunghezza/indicatore.
Per altre informazioni sull'uso di queste informazioni, vedere "Indirizzi buffer", più avanti in questa sezione. Per altre informazioni sull'associazione a livello di colonna, vedere Associazione a livello di colonna.
Associazione per riga
Nell'associazione a livello di riga, l'applicazione definisce una struttura che contiene buffer di dati e lunghezza/indicatore per ogni colonna da associare.
Per usare l'associazione a livello di riga, l'applicazione esegue i passaggi seguenti:
Definisce una struttura per contenere una singola riga di dati (inclusi i buffer di lunghezza e lunghezza/indicatore) e alloca una matrice di queste strutture.
Nota
Se l'applicazione scrive direttamente nei descrittori quando viene usata l'associazione a livello di riga, è possibile usare campi separati per i dati di lunghezza e indicatore.
Imposta l'attributo dell'istruzione SQL_ATTR_ROW_BIND_TYPE sulle dimensioni della struttura che contiene una singola riga di dati o sulle dimensioni di un'istanza di un buffer in cui verranno associate le colonne dei risultati. La lunghezza deve includere lo spazio per tutte le colonne associate e qualsiasi spaziatura interna della struttura o del buffer, per assicurarsi che quando l'indirizzo di una colonna associata viene incrementato con la lunghezza specificata, il risultato punterà all'inizio della stessa colonna nella riga successiva. Quando si usa l'operatore sizeof in ANSI C, questo comportamento è garantito.
Chiama SQLBindCol con gli argomenti seguenti per ogni colonna da associare:
TargetType è il tipo del membro del buffer di dati da associare alla colonna.
TargetValuePtr è l'indirizzo del membro del buffer di dati nel primo elemento della matrice.
BufferLength è la dimensione del membro del buffer di dati.
StrLen_or_IndPtr è l'indirizzo del membro di lunghezza/indicatore da associare.
Per altre informazioni sull'uso di queste informazioni, vedere "Indirizzi buffer", più avanti in questa sezione. Per altre informazioni sull'associazione a livello di colonna, vedere Binding a livello di riga.
Indirizzi buffer
L'indirizzo del buffer è l'indirizzo effettivo dei dati o del buffer di lunghezza/indicatore. Il driver calcola l'indirizzo del buffer subito prima della scrittura nei buffer, ad esempio durante il tempo di recupero. Viene calcolato dalla formula seguente, che usa gli indirizzi specificati negli argomenti TargetValuePtr e StrLen_or_IndPtr , l'offset di associazione e il numero di riga:
Offset binding di indirizzi + associati + ((numero di riga - 1) x dimensioni elemento)
dove le variabili della formula sono definite come descritto nella tabella seguente.
Variabile | Descrizione |
---|---|
Indirizzo associato | Per i buffer di dati, l'indirizzo specificato con l'argomento TargetValuePtr in SQLBindCol. Per i buffer di lunghezza/indicatore, l'indirizzo specificato con l'argomento StrLen_or_IndPtr in SQLBindCol. Per altre informazioni, vedere "Commenti aggiuntivi" nella sezione "Descrittori e SQLBindCol". Se l'indirizzo associato è 0, non viene restituito alcun valore di dati, anche se l'indirizzo calcolato dalla formula precedente è diverso da zero. |
Offset di associazione | Se viene utilizzata l'associazione per riga, il valore archiviato nell'indirizzo specificato con l'attributo di istruzione SQL_ATTR_ROW_BIND_OFFSET_PTR. Se viene utilizzata l'associazione a livello di colonna o se il valore dell'attributo dell'istruzione SQL_ATTR_ROW_BIND_OFFSET_PTR è un puntatore Null, Binding Offset è 0. |
Numero di riga | Numero in base 1 della riga nel set di righe. Per i recuperi a riga singola, ovvero l'impostazione predefinita, si tratta di 1. |
Dimensioni elemento | Dimensione di un elemento nella matrice associata. Se viene usata l'associazione a livello di colonna, si tratta di sizeof(SQLINTEGER) per buffer di lunghezza/indicatore. Per i buffer di dati, è il valore dell'argomento BufferLength in SQLBindCol se il tipo di dati è di lunghezza variabile e le dimensioni del tipo di dati se il tipo di dati è a lunghezza fissa. Se viene utilizzata l'associazione a livello di riga, si tratta del valore dell'attributo dell'istruzione SQL_ATTR_ROW_BIND_TYPE per i buffer di dati e di lunghezza/indicatore. |
Descrittori e SQLBindCol
Le sezioni seguenti descrivono in che modo SQLBindCol interagisce con i descrittori.
Attenzione
La chiamata a SQLBindCol per un'istruzione può influire sulle altre istruzioni. Ciò si verifica quando la ARD associata all'istruzione viene allocata in modo esplicito ed è associata anche ad altre istruzioni. Poiché SQLBindCol modifica il descrittore, le modifiche si applicano a tutte le istruzioni a cui è associato questo descrittore. Se questo non è il comportamento richiesto, l'applicazione deve dissociare questo descrittore dalle altre istruzioni prima di chiamare SQLBindCol.
Mapping degli argomenti
Concettualmente, SQLBindCol esegue i passaggi seguenti in sequenza:
Chiama SQLGetStmtAttr per ottenere l'handle ARD.
Chiama SQLGetDescField per ottenere il campo SQL_DESC_COUNT del descrittore e se il valore nell'argomento ColumnNumber supera il valore di SQL_DESC_COUNT, chiama SQLSetDescField per aumentare il valore di SQL_DESC_COUNT a ColumnNumber.
Chiama SQLSetDescField più volte per assegnare valori ai campi seguenti della ARD:
Imposta SQL_DESC_TYPE e SQL_DESC_CONCISE_TYPE sul valore di TargetType, ad eccezione del fatto che se TargetType è uno degli identificatori concisi di un sottotipo datetime o interval, imposta SQL_DESC_TYPE rispettivamente su SQL_DATETIME o SQL_INTERVAL, imposta SQL_DESC_CONCISE_TYPE sull'identificatore conciso e imposta SQL_DESC_DATETIME_INTERVAL_CODE sul codice secondario datetime o interval corrispondente.
Imposta una o più SQL_DESC_LENGTH, SQL_DESC_PRECISION, SQL_DESC_SCALE e SQL_DESC_DATETIME_INTERVAL_PRECISION, in base alle esigenze di TargetType.
Imposta il campo SQL_DESC_OCTET_LENGTH sul valore di BufferLength.
Imposta il campo SQL_DESC_DATA_PTR sul valore di TargetValuePtr.
Imposta il campo SQL_DESC_INDICATOR_PTR sul valore di StrLen_or_IndPtr. Vedere il paragrafo seguente.
Imposta il campo SQL_DESC_OCTET_LENGTH_PTR sul valore di StrLen_or_IndPtr. Vedere il paragrafo seguente.
La variabile a cui fa riferimento l'argomento StrLen_or_IndPtr viene utilizzata sia per le informazioni sull'indicatore che sulla lunghezza. Se un recupero rileva un valore Null per la colonna, archivia SQL_NULL_DATA in questa variabile; in caso contrario, archivia la lunghezza dei dati in questa variabile. Il passaggio di un puntatore Null come StrLen_or_IndPtr impedisce all'operazione di recupero di restituire la lunghezza dei dati, ma fa sì che il recupero abbia esito negativo se rileva un valore Null e non ha modo di restituire SQL_NULL_DATA.
Se la chiamata a SQLBindCol ha esito negativo, il contenuto dei campi descrittori che sarebbe stato impostato nel ARD non è definito e il valore del campo SQL_DESC_COUNT del ARD rimane invariato.
Reimpostazione implicita del campo COUNT
SQLBindCol imposta SQL_DESC_COUNT sul valore dell'argomento ColumnNumber solo quando aumenta il valore di SQL_DESC_COUNT. Se il valore nell'argomento TargetValuePtr è un puntatore Null e il valore nell'argomento ColumnNumber è uguale a SQL_DESC_COUNT ,ovvero quando si annulla l'associazione della colonna associata più alta, SQL_DESC_COUNT viene impostato sul numero della colonna associata rimanente più alta.
Avvertenze relative a SQL_DEFAULT
Per recuperare correttamente i dati della colonna, l'applicazione deve determinare correttamente la lunghezza e il punto iniziale dei dati nel buffer dell'applicazione. Quando l'applicazione specifica un TargetType esplicito, vengono rilevati facilmente errori di applicazione. Tuttavia, quando l'applicazione specifica un targetType di SQL_DEFAULT, SQLBindCol può essere applicato a una colonna di un tipo di dati diverso da quello previsto dall'applicazione, dalle modifiche ai metadati o applicando il codice a una colonna diversa. In questo caso, l'applicazione potrebbe non sempre determinare l'inizio o la lunghezza dei dati delle colonne recuperate. Ciò può causare errori di dati non segnalati o violazioni della memoria.
Esempio di codice
Nell'esempio seguente un'applicazione esegue un'istruzione SELECT nella tabella Customers per restituire un set di risultati degli ID cliente, dei nomi e dei numeri di telefono ordinati in base al nome. Chiama quindi SQLBindCol per associare le colonne di dati ai buffer locali. Infine, l'applicazione recupera ogni riga di dati con SQLFetch e stampa il nome, l'ID e il numero di telefono di ogni cliente.
Per altri esempi di codice, vedere Funzione SQLBulkOperations, funzione SQLColumns, funzione SQLFetchScroll e funzione SQLSetPos.
// SQLBindCol_ref.cpp
// compile with: odbc32.lib
#include <windows.h>
#include <stdio.h>
#define UNICODE
#include <sqlext.h>
#define NAME_LEN 50
#define PHONE_LEN 60
void show_error() {
printf("error\n");
}
int main() {
SQLHENV henv;
SQLHDBC hdbc;
SQLHSTMT hstmt = 0;
SQLRETURN retcode;
SQLWCHAR szName[NAME_LEN], szPhone[PHONE_LEN], sCustID[NAME_LEN];
SQLLEN cbName = 0, cbCustID = 0, cbPhone = 0;
// Allocate environment handle
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
// Set the ODBC version environment attribute
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);
// Allocate connection handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
// Set login timeout to 5 seconds
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
// Connect to data source
retcode = SQLConnect(hdbc, (SQLWCHAR*) L"NorthWind", SQL_NTS, (SQLWCHAR*) NULL, 0, NULL, 0);
// Allocate statement handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
retcode = SQLExecDirect(hstmt, (SQLWCHAR *) L"SELECT CustomerID, ContactName, Phone FROM CUSTOMERS ORDER BY 2, 1, 3", SQL_NTS);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
// Bind columns 1, 2, and 3
retcode = SQLBindCol(hstmt, 1, SQL_C_WCHAR, &sCustID, 100, &cbCustID);
retcode = SQLBindCol(hstmt, 2, SQL_C_WCHAR, szName, NAME_LEN, &cbName);
retcode = SQLBindCol(hstmt, 3, SQL_C_WCHAR, szPhone, PHONE_LEN, &cbPhone);
// Fetch and print each row of data. On an error, display a message and exit.
for (int i=0 ; ; i++) {
retcode = SQLFetch(hstmt);
if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO)
show_error();
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
//replace wprintf with printf
//%S with %ls
//warning C4477: 'wprintf' : format string '%S' requires an argument of type 'char *'
//but variadic argument 2 has type 'SQLWCHAR *'
//wprintf(L"%d: %S %S %S\n", i + 1, sCustID, szName, szPhone);
printf("%d: %ls %ls %ls\n", i + 1, sCustID, szName, szPhone);
}
else
break;
}
}
// Process data
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
SQLCancel(hstmt);
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
}
SQLDisconnect(hdbc);
}
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
}
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
}
Vedere anche Programma ODBC di esempio.
Funzioni correlate
Per informazioni su | Vedere |
---|---|
Restituzione di informazioni su una colonna in un set di risultati | Funzione SQLDescribeCol |
Recupero di un blocco di dati o scorrimento di un set di risultati | Funzione SQLFetchScroll |
Recupero di più righe di dati | Funzione SQLFetch |
Rilascio di buffer di colonna nell'istruzione | Funzione SQLFreeStmt |
Recupero di una parte o di una colonna di dati | Funzione SQLGetData |
Restituzione del numero di colonne del set di risultati | Funzione SQLNumResultCols |