Funzione SQLBindCol

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

Sommario
SQLBindCol lega i buffer dati applicativi alle colonne del set di risultati.

Sintassi

  
SQLRETURN SQLBindCol(  
      SQLHSTMT       StatementHandle,  
      SQLUSMALLINT   ColumnNumber,  
      SQLSMALLINT    TargetType,  
      SQLPOINTER     TargetValuePtr,  
      SQLLEN         BufferLength,  
      SQLLEN *       StrLen_or_IndPtr);  

Arguments

StatementHandle
[Input] Handle di istruzione.

Numero di colonna
[Input] Numero del set di risultati della colonna da bind. Le colonne sono numerate in ordine crescente a partire da 0, dove la colonna 0 è la colonna segnalibro. Se i segnalibri non vengono usati - cioè l'attributo SQL_ATTR_USE_BOOKMARKS istruzione è impostato su SQL_UB_OFF - allora i numeri delle colonne iniziano da 1.

TargetType
[Input] L'identificatore del tipo di dato C del buffer *TargetValuePtr . Quando recupera dati dalla sorgente dati con SQLFetch, SQLFetchScroll, SQLBulkOperations o SQLSetPos, il driver converte i dati in questo tipo; quando invia dati alla sorgente dati con SQLBulkOperations o SQLSetPos, il driver converte i dati da questo tipo. Per un elenco dei tipi di dati C validi e degli identificatori di tipo, consultare la sezione Tipi di Dati C nell'Appendice D: Tipi di Dati.

Se l'argomento TargetType è un tipo di dato a intervallo, per i dati vengono usate la precisione predefinita di precedenza dell'intervallo (2) e la precisione predefinita dei secondi dell'intervallo (6), come impostati rispettivamente nei campi SQL_DESC_DATETIME_INTERVAL_PRECISION e SQL_DESC_PRECISION dell'ARD. Se l'argomento TargetType è SQL_C_NUMERIC, per i dati vengono utilizzate la precisione predefinita (definita dal driver) e la scala predefinita (0), come impostate nei campi SQL_DESC_PRECISION e SQL_DESC_SCALE dell'ARD. Se una precisione o scala predefinita non è appropriata, l'applicazione dovrebbe impostare esplicitamente 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 Differito] Puntatore al buffer dati per associarsi alla colonna. SQLFetch e SQLFetchScroll restituiscono i dati in questo buffer. SQLBulkOperations restituisce dati in questo buffer quando Operation è SQL_FETCH_BY_BOOKMARK; recupera i dati da questo buffer quando l'Operazione è 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 nullo, il driver libera il data buffer per la colonna. Un'applicazione può liberare tutte le colonne chiamando SQLFreeStmt con l'opzione SQL_UNBIND. Un'applicazione può debinare il data buffer per una colonna ma avere comunque un limite di length/indicator buffer per la colonna, se l'argomento TargetValuePtr nella chiamata a SQLBindCol è un puntatore nullo ma l'argomento StrLen_or_IndPtr è un valore valido.

BufferLength
[Input] Lunghezza del buffer *TargetValuePtr in byte.

Il driver utilizza BufferLength per evitare di scrivere oltre la fine del buffer *TargetValuePtr quando restituisce dati a lunghezza variabile, come dati di caratteri o binari. Nota che il driver conta il carattere di null-termination quando restituisce i dati del carattere a *TargetValuePtr. * TargetValuePtr deve quindi contenere spazio per il carattere di null-termination, altrimenti il driver troncherà i dati.

Quando il driver restituisce dati a lunghezza fissa, come un intero o una struttura di data, ignora BufferLength e presume che il buffer sia abbastanza grande da contenere i dati. Pertanto, è importante che l'applicazione allochi un buffer sufficientemente grande per i dati a lunghezza fissa, altrimenti il driver scriverà oltre la fine del buffer.

SQLBindCol restituisce SQLSTATE HY090 (Lunghezza di stringa o buffer invalida) quando la lunghezza del buffer è inferiore a 0, ma non quando la lunghezza del buffer è 0. Tuttavia, se TargetType specifica un tipo di carattere, un'applicazione non dovrebbe impostare BufferLength a 0, perché i driver ISO conformi alla CLI restituiscono SQLSTATE HY090 (Stringa o buffer non valida) in quel caso.

StrLen_or_IndPtr
[Input/Output Differito] Puntatore al buffer di lunghezza/indicatore per 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 seguenti valori nel buffer length/indicator:

  • La lunghezza dei dati disponibili per restituire

  • SQL_NO_TOTAL

  • SQL_NULL_DATA

L'applicazione può inserire i seguenti valori nel buffer length/indicator per l'uso con SQLBulkOperations o SQLSetPos:

  • La lunghezza dei dati inviati

  • SQL_NTS

  • SQL_NULL_DATA

  • SQL_DATA_AT_EXEC

  • Il risultato del 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 ulteriori informazioni, consulta la Funzione SQLBulkOperations, la Funzione SQLFetch, la Funzione SQLSetPos e l'uso dei valori di lunghezza/indicatore.

Se StrLen_or_IndPtr è un puntatore nullo, non viene utilizzato alcun valore di lunghezza o indicatore. Questo è un errore quando si recuperano 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.

Returns

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR o SQL_INVALID_HANDLE.

Diagnostica

Quando SQLBindCol restituisce SQL_ERROR o SQL_SUCCESS_WITH_INFO, un valore SQLSTATE associato può essere ottenuto chiamando SQLGetDiagRec con un HandleType di SQL_HANDLE_STMT e un Handle di StatementHandle. La tabella seguente elenca i valori SQLSTATE tipicamente restituiti da SQLBindCol e li spiega nel contesto di questa funzione; la notazione "(DM)" precede le descrizioni degli stati SQL restituite dal Driver Manager. Il codice restituito associato a ogni valore SQLSTATE è SQL_ERROR, a meno che non sia specificato diversamente.

SQLSTATE Error Description
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 Numero Colonna era 0, e l'argomento Tipo Obiettivo non era SQL_C_BOOKMARK o SQL_C_VARBOOKMARK.
07009 Indice descrittore non valido Il valore specificato per l'argomento ColumnNumber superava il numero massimo di colonne nell'insieme 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 dato 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 veniva 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 era inferiore a 0.

(DM) Il pilota era un ODBC 2. x , l'argomento ColumnNumber era impostato a 0, e il valore specificato per l'argomento BufferLength non era 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 la sorgente dati non supporta la conversione specificata dalla combinazione dell'argomento TargetType e del tipo di dato SQL specifico del driver della colonna corrispondente.

L'argomento Numero di Colonna era 0 e il driver non supporta segnalibri.

Il driver supporta solo ODBC 2. x e l'argomento TargetType era uno dei seguenti:

SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT

e uno qualsiasi dei tipi di dati intervallo C elencati in C Tipi di Dati nell'Appendice D: Tipi di Dati.

Il driver supporta solo le versioni ODBC precedenti alla 3.50, e l'argomento TargetType era 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.

Comments

SQLBindCol viene utilizzato per associare, o bindare, colonne nell'insieme di risultati a buffer dati e buffer di lunghezza/indicatore nell'applicazione. Quando l'applicazione chiama SQLFetch, SQLFetchScroll o SQLSetPos per recuperare dati, il driver restituisce i dati delle colonne legate nei buffer specificati; per maggiori informazioni, vedi Funzione SQLFetch. Quando l'applicazione chiama SQLBulkOperations per aggiornare o inserire una riga oppure SQLSetPos per aggiornare una riga, il driver recupera i dati delle colonne vincolate dai buffer specificati; per maggiori informazioni, vedi Funzione SQLBulkOperations o Funzione SQLSetPos. Per maggiori informazioni sulla rilegazione, vedi Recupero dei risultati (Base).

Nota che le colonne non devono essere associate per recuperare i dati da esse. Un'applicazione può anche chiamare SQLGetData per recuperare dati dalle colonne. Sebbene sia possibile associare alcune colonne in una riga e chiamare SQLGetData per altre, ciò è soggetto a alcune restrizioni. Per maggiori informazioni, vedi SQLGetData.

Rilegatoria, Rilegatura e Rilegatura delle Colonne

Una colonna può essere vincolata, non vincolata o rimbalzata in qualsiasi momento, anche dopo che i dati sono stati prelevati dall'insieme dei risultati. Il nuovo binding entra in vigore la prossima volta che viene chiamata una funzione che utilizza binding. Ad esempio, supponiamo che un'applicazione leghi le colonne in un insieme di risultati e chiami SQLFetch. Il driver restituisce i dati nei buffer vincolati. Ora supponiamo che l'applicazione leghi le colonne a un insieme diverso di buffer. Il driver non inserisce i dati della riga appena recuperata nei buffer appena associati. Invece, aspetta che SQLFetch venga richiamato e poi posiziona i dati per la riga successiva nei buffer nuovi associati.

Note

L'attributo dell'istruzione SQL_ATTR_USE_BOOKMARKS dovrebbe sempre essere impostato prima di associare una colonna alla colonna 0. Non è obbligatorio ma è fortemente consigliato.

Collegamento delle 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 dati, e l'indirizzo di un buffer lunghezza/indicatore. Per informazioni su come questi indirizzi vengono utilizzati, vedi "Indirizzi Buffer", più avanti in questa sezione. Per maggiori informazioni sulle colonne di binding, vedi Using SQLBindCol.

L'uso di questi buffer è differito; cioè, l'applicazione li lega in SQLBindCol ma il driver vi accede da altre funzioni - ovvero SQLBulkOperations, SQLFetch, SQLFetchScroll o SQLSetPos. È responsabilità dell'applicazione assicurarsi che i puntatori specificati in SQLBindCol rimangano validi finché il binding rimane attivo. Se l'applicazione permette che questi puntatori diventino invalidi - ad esempio, libera un buffer - e poi chiama una funzione che si aspetta che siano validi, le conseguenze non sono definite. Per maggiori informazioni, vedi Buffers differiti.

Il binding rimane in vigore finché non viene sostituito da un nuovo binding, la colonna non viene vincolata o l'enunciato viene liberato.

Svincere le colonne

Per liberare una singola colonna, un'applicazione chiama SQLBindCol con ColumnNumber impostato al numero di quella colonna e TargetValuePtr impostato a un puntatore nullo. Se ColumnNumber si riferisce a una colonna non vincolata, SQLBindCol restituisce comunque SQL_SUCCESS.

Per liberare tutte le colonne, un'applicazione chiama SQLFreeStmt con fOption impostata su SQL_UNBIND. Questo può essere realizzato anche impostando il campo SQL_DESC_COUNT dell'ARD a zero.

Rilegatura delle colonne

Un'applicazione può eseguire una delle due operazioni per modificare un'associazione:

  • Chiama SQLBindCol per specificare un nuovo binding per una colonna già vincolata. Il driver sovrascrive l'associazione precedente con quella nuova.

  • Specificare un offset da aggiungere all'indirizzo buffer specificato dalla chiamata di binding a SQLBindCol. Per ulteriori informazioni, consulta la sezione successiva, "Binding Offsets."

Offset di Binding

Un binding offset è un valore che viene aggiunto agli indirizzi dei buffer dati e di lunghezza/indicatore (come specificato nell'argomento TargetValuePtr e StrLen_or_IndPtr ) prima che vengano dereferenziati. Quando vengono utilizzati gli offset, i bindings sono un "template" di come sono disposti i buffer dell'applicazione, e l'applicazione può spostare questo "template" in diverse aree di memoria modificando lo offset. Poiché lo stesso offset viene aggiunto a ciascun indirizzo in ogni binding, gli offset relativi tra buffer per colonne diverse devono essere gli stessi all'interno di ogni insieme di buffer. Questo è sempre vero quando si usa il binding riga per riga; L'applicazione deve disporre attentamente i suoi buffer affinché ciò sia vero quando si utilizza il binding colonna.

Usare un binding offset ha praticamente lo stesso effetto del ribinding di una colonna chiamando SQLBindCol. La differenza è che una nuova chiamata a SQLBindCol specifica nuovi indirizzi per il buffer dati e il buffer di lunghezza/indicatore, mentre l'uso di un binding offset non cambia gli indirizzi ma aggiunge solo un offset ad essi. L'applicazione può specificare un nuovo offset quando vuole, e questo offset viene sempre aggiunto agli indirizzi originariamente associati. In particolare, se l'offset è impostato a 0 o se l'attributo dell'istruzione è impostato a puntatore nullo, il driver utilizza gli indirizzi originariamente associati.

Per specificare un offset di binding, l'applicazione imposta l'attributo dell'istruzione SQL_ATTR_ROW_BIND_OFFSET_PTR all'indirizzo di un buffer SQLINTE. Prima che l'applicazione chiami una funzione che utilizza binding, inserisce un offset in byte in questo buffer. Per determinare l'indirizzo del buffer da utilizzare, il driver aggiunge lo offset all'indirizzo nel binding. La somma dell'indirizzo e dello spostamento deve essere un indirizzo valido, ma l'indirizzo a cui viene aggiunto l'offset non deve necessariamente essere valido. Per maggiori informazioni su come vengono utilizzati gli offset di binding, vedi "Indirizzi buffer", più avanti in questa sezione.

Array di Binding

Se la dimensione del set di righe (il valore dell'attributo SQL_ATTR_ROW_ARRAY_SIZE sentenza) è maggiore di 1, l'applicazione lega array di buffer invece che buffer singoli. Per maggiori informazioni, vedi Block Cursors.

L'applicazione può legare array in due modi:

  • Associare una matrice a ogni colonna. Questo è chiamato binding colonna per colonna perché ogni struttura dati (array) contiene dati per una singola colonna.

  • Definisci una struttura per contenere i dati per un'intera riga e associare un array di queste strutture. Questo è chiamato binding riga per riga perché ogni struttura dati contiene i dati di una singola riga.

Ogni array di buffer deve avere almeno tanti elementi quanto la dimensione del set di righe.

Note

Una domanda deve verificare che l'allineamento sia valido. Per maggiori informazioni sulle considerazioni sull'allineamento, vedi Allineamento.

Associazione Column-Wise

Nel binding colonna per colonna, l'applicazione assegna dati separati e array di lunghezza/indicatori a ciascuna colonna.

Per usare il binding colonna, l'applicazione imposta prima l'attributo dell'istruzione SQL_ATTR_ROW_BIND_TYPE a SQL_BIND_BY_COLUMN. Questa è l'impostazione predefinita. Per associare ogni colonna, l'applicazione esegue i passaggi seguenti:

  1. Alloca un array di buffer dati.

  2. Alloca una matrice di buffer di lunghezza/indicatore.

    Note

    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.

  3. Chiama SQLBindCol con i seguenti argomenti:

    • TargetType è il tipo di un singolo elemento nell'array del buffer dati.

    • TargetValuePtr è l'indirizzo dell'array del buffer dati.

    • BufferLength è la dimensione di un singolo elemento nell'array del buffer dati. L'argomento BufferLength viene ignorato quando i dati sono a lunghezza fissa.

    • StrLen_or_IndPtr è l'indirizzo della matrice di lunghezza/indicatore.

Per maggiori informazioni su come queste informazioni vengono utilizzate, vedi "Indirizzi Buffer", più avanti in questa sezione. Per maggiori informazioni sulla rilegatura a colonna, vedi Column-Wise Rilegatura.

associazione Row-Wise

Nel binding riga per riga, l'applicazione definisce una struttura che contiene dati e buffer di lunghezza/indicatore per ogni colonna da assegnare.

Per usare l'associazione a livello di riga, l'applicazione esegue i passaggi seguenti:

  1. Definisce una struttura per contenere una singola riga di dati (inclusi sia dati che buffer di lunghezza/indicatore) e alloca un array di queste strutture.

    Note

    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.

  2. Imposta l'attributo SQL_ATTR_ROW_BIND_TYPE istruzione alla dimensione della struttura che contiene una singola riga di dati o alla dimensione di un'istanza di buffer in cui saranno legate le colonne dei risultati. La lunghezza deve includere spazio per tutte le colonne legate e qualsiasi riempimento della struttura o del buffer, per assicurarsi che quando l'indirizzo di una colonna vincolata viene incrementato con la lunghezza specificata, il risultato indichi l'inizio della stessa colonna nella riga successiva. Quando si usa l'operatore sizeof in ANSI C, questo comportamento è garantito.

  3. Chiama SQLBindCol con i seguenti argomenti per ogni colonna da cogliere:

    • TargetType è il tipo di membro del data buffer da associare alla colonna.

    • TargetValuePtr è l'indirizzo del membro del data buffer nel primo elemento dell'array.

    • BufferLength è la dimensione del membro del buffer dati.

    • StrLen_or_IndPtr è l'indirizzo del membro di lunghezza/indicatore da associare.

Per maggiori informazioni su come queste informazioni vengono utilizzate, vedi "Indirizzi Buffer", più avanti in questa sezione. Per maggiori informazioni sulla rilegatura a colonna, vedi Row-Wise Rilegatura.

Indirizzi buffer

L'indirizzo del buffer è l'indirizzo effettivo dei dati o del buffer di lunghezza/indicatore. Il driver calcola l'indirizzo del buffer poco prima di scrivere nei buffer (ad esempio durante il tempo di recupero). Si calcola dalla seguente formula, che utilizza gli indirizzi specificati negli argomenti TargetValuePtr e StrLen_or_IndPtr , lo offset di binding e il numero di riga:

Indirizzo + vincolatoOffset di Binding + ((Numero Riga - 1) x Dimensione Elemento)

dove le variabili della formula sono definite come descritto nella tabella seguente.

Variabile Description
Indirizzo vincolato Per i data buffer, 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 maggiori informazioni, consulta "Commenti aggiuntivi" nella sezione "Descrittori e SQLBindCol".

Se l'indirizzo vincente è 0, non viene restituito alcun valore di dato, anche se l'indirizzo calcolato dalla formula precedente è diverso da zero.
Offset di rilacciatura Se si usa binding riga per riga, il valore memorizzato all'indirizzo specificato con l'attributo SQL_ATTR_ROW_BIND_OFFSET_PTR sentenza.

Se si usa binding colonna per colonna o se il valore dell'attributo SQL_ATTR_ROW_BIND_OFFSET_PTR instruction è un puntatore nullo, il Binding Offset è 0.
Numero di riga Il numero basato su 1 della riga nell'insieme di righe. Per i recuperi a singola riga, che sono predefiniti, questo è 1.
Dimensione degli elementi La dimensione di un elemento nell'array legato.

Se si usa binding colonna per colonna, questo è sizeof(SQLINTEGER) per i buffer length/indicator. Per i data buffer, è il valore dell'argomento BufferLength in SQLBindCol se il tipo di dato è di lunghezza variabile, e la dimensione del tipo di dato se il tipo di dato è di lunghezza fissa.

Se si usa binding riga per riga, questo è il valore dell'attributo SQL_ATTR_ROW_BIND_TYPE istruzione sia per i dati che per i buffer di lunghezza/indicatore.

Descrittori e SQLBindCol

Le sezioni seguenti descrivono come SQLBindCol interagisce con i descrittori.

Caution

Chiamare SQLBindCol per una istruzione può influenzare 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 questo descrittore è associato. Se questo non è il comportamento richiesto, l'applicazione dovrebbe dissociare questo descrittore dalle altre istruzioni prima di chiamare SQLBindCol.

Scambi di argomentazione

Concettualmente, SQLBindCol esegue i seguenti passaggi in sequenza:

  1. Chiama SQLGetStmtAttr per ottenere l'handle ARD.

  2. Chiama SQLGetDescField per ottenere il campo SQL_DESC_COUNT di questo 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.

  3. Chiama SQLSetDescField più volte per assegnare valori ai seguenti campi dell'ARD:

    • Imposta SQL_DESC_TYPE e SQL_DESC_CONCISE_TYPE al valore di TargetType, tranne che se TargetType è uno degli identificatori concisi di un sottotipo datatime o intervallo, imposta SQL_DESC_TYPE a SQL_DATETIME o SQL_INTERVAL, rispettivamente; imposta SQL_DESC_CONCISE_TYPE all'identificatore conciso; e imposta SQL_DESC_DATETIME_INTERVAL_CODE al corrispondente sottocodice data-ora o intervallo.

    • Imposta uno o più SQL_DESC_LENGTH, SQL_DESC_PRECISION, SQL_DESC_SCALE e SQL_DESC_DATETIME_INTERVAL_PRECISION, a seconda di TargetType.

    • Imposta il campo SQL_DESC_OCTET_LENGTH sul valore di BufferLength.

    • Imposta il campo SQL_DESC_DATA_PTR al valore di TargetValuePtr.

    • Imposta il campo SQL_DESC_INDICATOR_PTR al valore di StrLen_or_IndPtr. (Vedi il paragrafo seguente.)

    • Imposta il campo SQL_DESC_OCTET_LENGTH_PTR al valore di StrLen_or_IndPtr. (Vedi il paragrafo seguente.)

La variabile a cui si riferisce l'argomento StrLen_or_IndPtr viene utilizzata sia per l'indicazione che per l'informazione sulla lunghezza. Se un fetch incontra un valore nullo per la colonna, memorizza SQL_NULL_DATA in questa variabile; altrimenti, memorizza la lunghezza dei dati in questa variabile. Passare un puntatore nullo come StrLen_or_IndPtr impedisce all'operazione di recupero di restituire la lunghezza dei dati, ma fa fallire il recupero se incontra un valore nullo e non ha modo di restituire SQL_NULL_DATA.

Se la chiamata a SQLBindCol fallisce, il contenuto dei campi descrittori che avrebbe impostato nell'ARD è indefinito e il valore del campo SQL_DESC_COUNT dell'ARD rimane invariato.

Ripristino implicito del campo COUNT

SQLBindCol imposta SQL_DESC_COUNT al valore dell'argomento ColumnNumber solo quando questo aumenterebbe il valore di SQL_DESC_COUNT. Se il valore nell'argomento TargetValuePtr è un puntatore nullo e il valore nell'argomento ColumnNumber è uguale a SQL_DESC_COUNT (cioè, quando si svince la colonna con il vincolo più alto), allora SQL_DESC_COUNT è impostato al numero della colonna rimasta con il limite più alto.

Precauzioni riguardo SQL_DEFAULT

Per recuperare con successo i dati delle colonne, l'applicazione deve determinare correttamente la lunghezza e il punto di partenza dei dati nel buffer applicativo. Quando l'applicazione specifica un TargetType esplicito, i fraintendimenti applicativi sono facilmente rilevati. Tuttavia, quando l'applicazione specifica un Target Type di SQL_DEFAULT, SQLBindCol può essere applicato a una colonna di un tipo di dato diverso da quello previsto dall'applicazione, sia per modifiche ai metadati sia applicando il codice a una colonna diversa. In questo caso, l'applicazione potrebbe non sempre determinare l'inizio o la lunghezza dei dati della colonna recuperati. Questo può portare a errori di dati non segnalati o a violazioni di memoria.

Esempio di codice

Nel seguente esempio, un'applicazione esegue un'istruzione SELECT sulla tabella Customers per restituire un insieme di risultati degli ID clienti, nomi e numeri di telefono, ordinati per nome. Successivamente chiama SQLBindCol per associare le colonne dei 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, vedi 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);  
   }  
}  

Vedi anche, Programma ODBC di esempio.

Per informazioni su Vedi
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 sull'istruzione Funzione SQLFreeStmt
Recupero di una parte o di una colonna di dati Funzione SQLGetData
Restituendo il numero di colonne dell'insieme dei risultati Funzione SQLNumResultCols