Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Conformidade
Versão Introduzida: Normas ODBC 1.0 Conformidade: ISO 92
Summary
O SQLBindCol liga buffers de dados de aplicação a colunas no conjunto de resultados.
Syntax
SQLRETURN SQLBindCol(
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLSMALLINT TargetType,
SQLPOINTER TargetValuePtr,
SQLLEN BufferLength,
SQLLEN * StrLen_or_IndPtr);
Arguments
HandleStatement
[Entrada] Identificador do extrato.
Número da Coluna
[Entrada] Número da coluna do conjunto de resultados a bind. As colunas são numeradas por ordem crescente das colunas a partir de 0, onde a coluna 0 é a coluna de marcação. Se os marcadores não forem usados – ou seja, o atributo da instrução SQL_ATTR_USE_BOOKMARKS for definido para SQL_UB_OFF – então os números das colunas começam em 1.
Tipo de Alvo
[Entrada] O identificador do tipo de dados C do buffer *TargetValuePtr . Quando está a recuperar dados da fonte de dados com SQLFetch, SQLFetchScroll, SQLBulkOperations ou SQLSetPos, o driver converte os dados para este tipo; quando envia dados para a fonte de dados com SQLBulkOperations ou SQLSetPos, o driver converte os dados deste tipo. Para uma lista de tipos de dados C válidos e identificadores de tipo, consulte a secção Tipos de Dados C no Apêndice D: Tipos de Dados.
Se o argumento TargetType for um tipo de dado de intervalo, são usadas para os dados a precisão padrão de intervalo inicial (2) e a precisão de intervalo de segundos padrão (6), conforme definidas nos campos SQL_DESC_DATETIME_INTERVAL_PRECISION e SQL_DESC_PRECISION do ARD, respetivamente. Se o argumento TargetType for SQL_C_NUMERIC, a precisão padrão (definida pelo driver) e a escala padrão (0), definidas nos campos SQL_DESC_PRECISION e SQL_DESC_SCALE do ARD, são usadas para os dados. Se qualquer precisão ou escala padrão não for adequada, a aplicação deve definir explicitamente o campo descritor apropriado através de uma chamada para SQLSetDescField ou SQLSetDescRec.
Também pode especificar um tipo de dado C estendido. Para mais informações, consulte Tipos de Dados C no ODBC.
TargetValuePtr
[Entrada/Saída Diferida] Aponta para o buffer de dados para ligar à coluna.
SQLFetch e SQLFetchScroll devolvem dados neste buffer.
O SQLBulkOperations devolve dados neste buffer quando a Operação está SQL_FETCH_BY_BOOKMARK; recupera dados deste buffer quando a Operação está SQL_ADD ou SQL_UPDATE_BY_BOOKMARK.
O SQLSetPos devolve dados neste buffer quando a Operação é SQL_REFRESH; recupera dados deste buffer quando a Operação está SQL_UPDATE.
Se o TargetValuePtr for um ponteiro nulo, o driver desvincula o buffer de dados da coluna. Uma aplicação pode desvincular todas as colunas chamando SQLFreeStmt com a opção SQL_UNBIND. Uma aplicação pode desvincular o buffer de dados de uma coluna mas ainda assim ter um limite de buffer de comprimento/indicador para a coluna, se o argumento TargetValuePtr na chamada ao SQLBindCol for um ponteiro nulo, mas o argumento StrLen_or_IndPtr for um valor válido.
BufferLength
[Entrada] Comprimento do buffer *TargetValuePtr em bytes.
O driver utiliza o BufferLength para evitar escrever para além do fim do *TargetValuePtr buffer quando devolve dados de comprimento variável, como dados de caracteres ou binários. Note que o driver conta o carácter de terminação nula quando retorna os dados do carácter para *TargetValuePtr. * O TargetValuePtr deve, portanto, conter espaço para o carácter de terminação nula, caso contrário o driver truncará os dados.
Quando o driver devolve dados de comprimento fixo, como um inteiro ou uma estrutura de data, ignora o BufferLength e assume que o buffer é suficientemente grande para armazenar os dados. Por isso, é importante que a aplicação aloque um buffer suficientemente grande para dados de comprimento fixo, caso contrário o driver irá escrever para além do fim do buffer.
O SQLBindCol devolve SQLSTATE HY090 (comprimento de string ou buffer inválido) quando o BufferLength é inferior a 0, mas não quando o BufferLength é 0. No entanto, se o TargetType especificar um tipo de carácter, uma aplicação não deve definir o BufferLength para 0, porque os drivers compatíveis com ISO CLI retornam SQLSTATE HY090 (Comprimento de string ou buffer inválido) nesse caso.
StrLen_or_IndPtr
[Entrada/Saída Diferida] Aponta para o buffer de comprimento/indicador para ligar à coluna.
SQLFetch e SQLFetchScroll retornam um valor neste buffer.
O SQLBulkOperations recupera um valor deste buffer quando a Operação está SQL_ADD, SQL_UPDATE_BY_BOOKMARK ou SQL_DELETE_BY_BOOKMARK.
O SQLBulkOperations devolve um valor neste buffer quando Operation está SQL_FETCH_BY_BOOKMARK.
O SQLSetPos devolve um valor neste buffer quando a Operação é SQL_REFRESH; recupera um valor deste buffer quando a Operação está SQL_UPDATE.
SQLFetch, SQLFetchScroll, SQLBulkOperations e SQLSetPos podem devolver os seguintes valores no buffer de comprimento/indicador:
O comprimento dos dados disponíveis para devolver
SQL_NO_TOTAL
SQL_NULL_DATA
A aplicação pode colocar os seguintes valores no buffer de comprimento/indicador para uso com SQLBulkOperations ou SQLSetPos:
O comprimento dos dados enviados
SQL_NTS
SQL_NULL_DATA
SQL_DATA_AT_EXEC
O resultado do macro SQL_LEN_DATA_AT_EXEC
SQL_COLUMN_IGNORE
Se o buffer indicador e o buffer de comprimento forem buffers separados, o buffer indicador pode devolver apenas SQL_NULL_DATA, enquanto o buffer de comprimento pode devolver todos os outros valores.
Para mais informações, consulte Função SQLBulkOperations, Função SQLFetch, Função SQLSetPos e Utilização de Valores de Comprimento/Indicador.
Se StrLen_or_IndPtr for um ponteiro nulo, não é usado valor de comprimento ou indicador. Isto é um erro ao recolher dados e os dados são NULL.
Consulte a Informação ODBC de 64 Bits, se a sua aplicação funcionar num sistema operativo de 64 bits.
Devoluções
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR ou SQL_INVALID_HANDLE.
Diagnósticos
Quando o SQLBindCol devolve SQL_ERROR ou SQL_SUCCESS_WITH_INFO, um valor SQLSTATE associado pode ser obtido chamando SQLGetDiagRec com um HandleType de SQL_HANDLE_STMT e um Handle de StatementHandle. A tabela seguinte lista os valores SQLSTATE normalmente devolvidos pelo SQLBindCol e explica cada um no contexto desta função; a notação "(DM)" precede as descrições dos SQLSTATEs devolvidas pelo Gestor de Drivers. O código de retorno associado a cada valor SQLSTATE é SQL_ERROR, salvo indicação em contrário.
| SQLSTATE | Erro | Descrição |
|---|---|---|
| 01000 | Aviso geral | Mensagem informativa específica para o condutor. (Função devolve SQL_SUCCESS_WITH_INFO.) |
| 07006 | Violação de atributo de tipo de dado restrito | (DM) O argumento ColumnNumber era 0, e o argumento TargetType não era SQL_C_BOOKMARK nem SQL_C_VARBOOKMARK. |
| 07009 | Índice de descritores inválido | O valor especificado para o argumento ColumnNumber excedeu o número máximo de colunas no conjunto de resultados. |
| HY000 | Erro geral | Ocorreu um erro para o qual não existia um SQLSTATE específico e para o qual não estava definido nenhum SQLSTATE específico da implementação. A mensagem de erro devolvida pelo SQLGetDiagRec no buffer *MessageText descreve o erro e a sua causa. |
| HY001 | Erro de alocação de memória | O controlador não conseguiu alocar a memória necessária para suportar a execução ou conclusão da função. |
| HY003 | Tipo de buffer de aplicação inválido | O argumento TargetType não era nem um tipo de dado válido nem SQL_C_DEFAULT. |
| HY010 | Erro de sequência de funções | (DM) Uma função de execução assíncrona era chamada para o handle de ligação associado ao StatementHandle. Esta função assíncrona ainda estava a ser executada quando o SQLBindCol foi chamado. (DM) SQLExecute, SQLExecDirect ou SQLMoreResults era chamado para o StatementHandle e devolvido SQL_PARAM_DATA_AVAILABLE. Esta função era chamada antes de os dados serem recuperados para todos os parâmetros transmitidos. (DM) Uma função de execução assíncrona era chamada para o StatementHandle e ainda estava a correr quando esta função foi chamada. (DM) SQLExecute, SQLExecDirect, SQLBulkOperations ou SQLSetPos era chamado para o StatementHandle e devolvido SQL_NEED_DATA. Esta função era chamada antes de os dados serem enviados para todos os parâmetros ou colunas de dados na execução. |
| HY013 | Erro de gestão de memória | A chamada de função não podia ser processada porque os objetos de memória subjacentes não podiam ser acedidos, possivelmente devido a condições de baixa memória. |
| HY090 | Comprimento inválido da corda ou do buffer | (DM) O valor especificado para o argumento BufferLength era inferior a 0. (DM) O condutor era um ODBC 2. x , o argumento ColumnNumber foi definido para 0, e o valor especificado para o argumento BufferLength não era igual a 4. |
| HY117 | A ligação é suspensa devido ao estado desconhecido da transação. Apenas funções de desconexão e de leitura são permitidas. | (DM) Para mais informações sobre o estado suspenso, veja Função SQLEndTran. |
| HYC00 | Funcionalidade opcional não implementada | O driver ou fonte de dados não suporta a conversão especificada pela combinação do argumento TargetType e do tipo de dado SQL específico do driver da coluna correspondente. O argumento Número da Coluna era 0 e o condutor não suporta marcadores. O driver suporta apenas ODBC 2. x e o argumento TargetType foi um dos seguintes: SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT e qualquer um dos tipos de dados de intervalo C listados em Tipos de Dados C no Apêndice D: Tipos de Dados. O driver só suporta versões ODBC anteriores à 3.50, e o argumento TargetType era SQL_C_GUID. |
| HYT01 | Expirou o tempo limite de ligação | O período de timeout da ligação expirou antes de a fonte de dados responder ao pedido. O período de tempo de expiração da ligação é definido através do SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT. |
| IM001 | O driver não suporta esta função | (DM) O driver associado ao StatementHandle não suporta a função. |
Comments
O SQLBindCol é usado para associar, ou atribuir, colunas no conjunto de resultados a buffers de dados e buffers de comprimento/indicador na aplicação. Quando a aplicação chama SQLFetch, SQLFetchScroll ou SQLSetPos para obter dados, o driver devolve os dados das colunas limitadas nos buffers especificados; para mais informações, consulte Função SQLFetch. Quando a aplicação chama SQLBulkOperations para atualizar ou inserir uma linha ou SQLSetPos para atualizar uma linha, o driver recupera os dados das colunas limitadas dos buffers especificados; para mais informações, consulte Função SQLBulkOperations ou Função SQLSetPos. Para mais informações sobre ligação, consulte Recuperar Resultados (Básico).
Note que as colunas não precisam de ser vinculadas para obter dados delas. Uma aplicação pode também chamar SQLGetData para recuperar dados das colunas. Embora seja possível atribuir algumas colunas numa linha e chamar SQLGetData para outras, isto está sujeito a algumas restrições. Para mais informações, consulte SQLGetData.
Colunas de Encadernação, Desencadernação e Reencadernação
Uma coluna pode ser limitada, não vinculada ou rebound a qualquer momento, mesmo depois de os dados terem sido recolhidos do conjunto de resultados. A nova ligação entra em vigor na próxima vez que uma função que usa ligações é chamada. Por exemplo, suponha que uma aplicação liga as colunas de um conjunto de resultados e chama SQLFetch. O driver devolve os dados nos buffers limitados. Agora suponha que a aplicação liga as colunas a um conjunto diferente de buffers. O driver não coloca os dados da linha recém-buscada nos buffers recém-atribuídos. Em vez disso, espera até que o SQLFetch seja chamado novamente e depois coloca os dados da próxima linha nos buffers recém-ligados.
Note
O atributo da instrução SQL_ATTR_USE_BOOKMARKS deve sempre ser definido antes de associar uma coluna à coluna 0. Isto não é obrigatório, mas é fortemente recomendado.
Colunas de vinculação
Para associar uma coluna, uma aplicação chama SQLBindCol e passa o número da coluna, tipo, endereço e comprimento de um buffer de dados, bem como o endereço de um buffer de comprimento/indicador. Para informações sobre como estes endereços são utilizados, consulte "Endereços de Buffer", mais adiante nesta secção. Para mais informações sobre colunas de ligação, consulte Using SQLBindCol.
A utilização destes buffers é adiada; ou seja, a aplicação liga-as no SQLBindCol , mas o driver acede-as a partir de outras funções – nomeadamente SQLBulkOperations, SQLFetch, SQLFetchScroll ou SQLSetPos. É responsabilidade da aplicação garantir que os ponteiros especificados no SQLBindCol permanecem válidos enquanto a ligação estiver em vigor. Se a aplicação permitir que estes ponteiros se tornem inválidos – por exemplo, libertar um buffer – e depois chamar uma função que espera que sejam válidos, as consequências ficam indefinidas. Para mais informações, consulte Buffers Diferidos.
A ligação mantém-se ativa até ser substituída por uma nova ligação, a coluna ser desvinculada ou a afirmação ser libertada.
Desencadernação das Colunas
Para desligar uma única coluna, uma aplicação chama SQLBindCol com ColumnNumber definido para o número dessa coluna e TargetValuePtr definido para um ponteiro nulo. Se ColumnNumber se referir a uma coluna não vinculada, SQLBindCol ainda devolve SQL_SUCCESS.
Para desvincular todas as colunas, uma aplicação chama SQLFreeStmt com fOption definido para SQL_UNBIND. Isto também pode ser conseguido definindo o campo SQL_DESC_COUNT do ARD a zero.
Colunas de Reencadernação
Uma aplicação pode realizar uma de duas operações para alterar uma ligação:
Ligue ao SQLBindCol para especificar uma nova ligação para uma coluna que já está vinculada. O driver sobrescrive a ligação antiga pela nova.
Especifique um offset a ser adicionado ao endereço do buffer que foi especificado pela chamada de ligação ao SQLBindCol. Para mais informações, consulte a secção seguinte, "Deslocamentos de Ligação."
Deslocamentos de ligação
Um deslocamento de ligação é um valor que é adicionado aos endereços dos buffers de dados e comprimento/indicador (conforme especificado no argumento TargetValuePtr e StrLen_or_IndPtr ) antes de serem desreferenciados. Quando são usados deslocamentos, as ligações são um "modelo" de como os buffers da aplicação estão dispostos, e a aplicação pode mover este "modelo" para diferentes áreas da memória alterando o deslocamento. Como o mesmo offset é adicionado a cada endereço em cada binding, os deslocamentos relativos entre buffers para diferentes colunas devem ser os mesmos dentro de cada conjunto de buffers. Isto é sempre verdade quando se usa ligação por linha; A aplicação deve dispor cuidadosamente os seus buffers para que isto seja verdade quando se usa a ligação por coluna.
Usar um offset de binding tem basicamente o mesmo efeito que rebinding uma coluna ao chamar SQLBindCol. A diferença é que uma nova chamada ao SQLBindCol especifica novos endereços para o buffer de dados e para o buffer de comprimento/indicador, enquanto o uso de um offset de binding não altera os endereços, apenas acrescenta um offset a eles. A aplicação pode especificar um novo deslocamento sempre que quiser, e esse deslocamento é sempre adicionado aos endereços originalmente atribuídos. Em particular, se o deslocamento estiver definido para 0 ou se o atributo da instrução for definido para um ponteiro nulo, o driver usa os endereços originalmente atribuídos.
Para especificar um deslocamento de ligação, a aplicação define o atributo da instrução SQL_ATTR_ROW_BIND_OFFSET_PTR para o endereço de um buffer SQLINTEIR. Antes de a aplicação chamar uma função que usa bindings, coloca um offset em bytes nesse buffer. Para determinar o endereço do buffer a utilizar, o driver adiciona o offset ao endereço na ligação. A soma do endereço e do deslocamento deve ser um endereço válido, mas o endereço ao qual o deslocamento é adicionado não tem de ser válido. Para mais informações sobre como os deslocamentos de ligação são usados, veja "Endereços de Buffer", mais adiante nesta secção.
Matrizes de Ligação
Se o tamanho do conjunto de linhas (o valor do atributo da instrução SQL_ATTR_ROW_ARRAY_SIZE) for maior que 1, a aplicação associa arrays de buffers em vez de buffers individuais. Para mais informações, consulte Cursores de Bloco.
A aplicação pode ligar arrays de duas formas:
Associe um array a cada coluna. Isto é conhecido como ligação coluna a coluna porque cada estrutura de dados (array) contém dados para uma única coluna.
Defina uma estrutura para armazenar os dados de uma linha inteira e associe um array dessas estruturas. Isto é referido como ligação linha a linha porque cada estrutura de dados contém os dados para uma única linha.
Cada array de buffers deve ter pelo menos tantos elementos quanto o tamanho do conjunto de linhas.
Note
Uma candidatura deve verificar que o alinhamento é válido. Para mais informações sobre considerações de alinhamento, consulte Alinhamento.
Column-Wise Vinculação
Na ligação coluna a coluna, a aplicação associa dados separados e arrays de comprimento/indicador a cada coluna.
Para usar a ligação coluna a coluna, a aplicação define primeiro o atributo da instrução SQL_ATTR_ROW_BIND_TYPE para SQL_BIND_BY_COLUMN. (Este é o padrão.) Para cada coluna a ser limitada, a aplicação executa os seguintes passos:
Aloca um array de buffer de dados.
Aloca um array de buffers de comprimento/indicadores.
Note
Se a aplicação escrever diretamente nos descritores quando é usada ligação por colunas, podem ser usados arrays separados para dados de comprimento e indicadores.
Chama SQLBindCol com os seguintes argumentos:
TargetType é o tipo de um único elemento no array de buffer de dados.
TargetValuePtr é o endereço do array de buffer de dados.
BufferLength é o tamanho de um único elemento no array do buffer de dados. O argumento BufferLength é ignorado quando os dados são dados de comprimento fixo.
StrLen_or_IndPtr é o endereço da matriz de comprimento/indicador.
Para mais informações sobre como esta informação é utilizada, consulte "Endereços de Buffer", mais adiante nesta secção. Para mais informações sobre encadernação por coluna, veja Column-Wise Encadernação.
Row-Wise Vinculação
Na ligação por linhas, a aplicação define uma estrutura que contém dados e buffers de comprimento/indicador para cada coluna a encadenar.
Para usar a ligação por linhas, a aplicação executa os seguintes passos:
Define uma estrutura para armazenar uma única linha de dados (incluindo tanto dados como buffers de comprimento/indicador) e aloca um array dessas estruturas.
Note
Se a aplicação escrever diretamente em descritores quando é usada ligação por linhas, podem ser usados campos separados para dados de comprimento e indicadores.
Define o atributo SQL_ATTR_ROW_BIND_TYPE de instrução ao tamanho da estrutura que contém uma única linha de dados ou ao tamanho de uma instância de um buffer onde as colunas de resultados serão encadernadas. O comprimento deve incluir espaço para todas as colunas limitadas, e qualquer preenchimento da estrutura ou buffer, para garantir que, quando o endereço de uma coluna limitada for incrementado com o comprimento especificado, o resultado aponte para o início da mesma coluna na linha seguinte. Ao usar o operador sizeof no ANSI C, este comportamento é garantido.
Chama SQLBindCol com os seguintes argumentos para cada coluna a ser limitada:
TargetType é o tipo do membro do buffer de dados a ser associado à coluna.
TargetValuePtr é o endereço do membro do buffer de dados no primeiro elemento do array.
BufferLength é o tamanho do membro do buffer de dados.
StrLen_or_IndPtr é o endereço do membro do comprimento/indicador a ser encadernado.
Para mais informações sobre como esta informação é utilizada, consulte "Endereços de Buffer", mais adiante nesta secção. Para mais informações sobre encadernação por coluna, veja Row-Wise Encadernação.
Endereços de Buffer
O endereço do buffer é o endereço real do buffer de dados ou do buffer de comprimento/indicador. O driver calcula o endereço do buffer pouco antes de escrever nos buffers (como durante o tempo de busca). É calculado a partir da seguinte fórmula, que utiliza os endereços especificados nos argumentos TargetValuePtr e StrLen_or_IndPtr , o deslocamento de ligação e o número da linha:
Endereço + VinculadoDeslocamento de ligação + ((Número da Linha - 1) x Tamanho do Elemento)
onde as variáveis da fórmula são definidas conforme descrito na tabela seguinte.
| Variable | Descrição |
|---|---|
| Endereço Vinculado | Para buffers de dados, o endereço especificado com o argumento TargetValuePtr no SQLBindCol. Para buffers de comprimento/indicador, o endereço especificado com o argumento StrLen_or_IndPtr no SQLBindCol. Para mais informações, consulte "Comentários Adicionais" na secção "Descriptors and SQLBindCol". Se o endereço limitado for 0, nenhum valor de dados é devolvido, mesmo que o endereço calculado pela fórmula anterior seja diferente de zero. |
| Deslocamento de encadernação | Se for usada ligação por linhas, o valor armazenado no endereço especificado com o atributo da instrução SQL_ATTR_ROW_BIND_OFFSET_PTR. Se for usada ligação coluna a coluna ou se o valor do atributo da instrução SQL_ATTR_ROW_BIND_OFFSET_PTR for um ponteiro nulo, o Deslocamento de Ligação é 0. |
| Número da Fila | O número baseado em 1 da linha no conjunto de linhas. Para buscas de linha única, que são o padrão, isto é 1. |
| Tamanho dos elementos | O tamanho de um elemento no array limitado. Se for usada a ligação por colunas, isto é sizeof(SQLINTEGER) para buffers de comprimento/indicador. Para buffers de dados, é o valor do argumento BufferLength no SQLBindCol se o tipo de dado for de comprimento variável, e o tamanho do tipo de dado se o tipo de dado for de comprimento fixo. Se for usada ligação por linhas, este é o valor do atributo SQL_ATTR_ROW_BIND_TYPE instrução tanto para os dados como para os buffers de comprimento/indicador. |
Descriptors e SQLBindCol
As secções seguintes descrevem como o SQLBindCol interage com os descritores.
Caution
Chamar SQLBindCol para uma instrução pode afetar outras. Isto ocorre quando o ARD associado à instrução é explicitamente alocado e também está associado a outras instruções. Como o SQLBindCol modifica o descritor, as modificações aplicam-se a todas as instruções com as quais este descritor está associado. Se este não for o comportamento exigido, a aplicação deve dissociar este descritor das outras instruções antes de chamar SQLBindCol.
Mapeamentos de Argumentos
Conceptualmente, o SQLBindCol executa os seguintes passos em sequência:
Chama SQLGetStmtAttr para obter o handle ARD.
Chama SQLGetDescField para obter o campo SQL_DESC_COUNT deste descritor e, se o valor no argumento ColumnNumber exceder o valor de SQL_DESC_COUNT, chama SQLSetDescField para aumentar o valor de SQL_DESC_COUNT para ColumnNumber.
Chama SQLSetDescField várias vezes para atribuir valores aos seguintes campos do ARD:
Define SQL_DESC_TYPE e SQL_DESC_CONCISE_TYPE ao valor de TargetType, exceto que, se TargetType for um dos identificadores concisos de um subtipo de data-hora ou intervalo, define SQL_DESC_TYPE para SQL_DATETIME ou SQL_INTERVAL, respetivamente; define SQL_DESC_CONCISE_TYPE ao identificador conciso; e define SQL_DESC_DATETIME_INTERVAL_CODE para o correspondente subcódigo de data-hora ou intervalo.
Define um ou mais de SQL_DESC_LENGTH, SQL_DESC_PRECISION, SQL_DESC_SCALE e SQL_DESC_DATETIME_INTERVAL_PRECISION, conforme apropriado para TargetType.
Define o campo SQL_DESC_OCTET_LENGTH para o valor de BufferLength.
Define o campo SQL_DESC_DATA_PTR para o valor de TargetValuePtr.
Define o campo SQL_DESC_INDICATOR_PTR para o valor de StrLen_or_IndPtr. (Ver o parágrafo seguinte.)
Define o campo SQL_DESC_OCTET_LENGTH_PTR para o valor de StrLen_or_IndPtr. (Ver o parágrafo seguinte.)
A variável a que o argumento StrLen_or_IndPtr se refere é usada tanto para informação de indicador como de comprimento. Se um fetch encontrar um valor nulo para a coluna, armazena SQL_NULL_DATA nessa variável; caso contrário, armazena o comprimento dos dados nesta variável. Passar um ponteiro nulo como StrLen_or_IndPtr impede que a operação de busca devolva o comprimento dos dados, mas faz com que a busca falhe se encontrar um valor nulo e não tiver forma de devolver SQL_NULL_DATA.
Se a chamada ao SQLBindCol falhar, o conteúdo dos campos de descrição que teria definido no ARD fica indefinido e o valor do campo SQL_DESC_COUNT do ARD mantém-se inalterado.
Reinício Implícito do Campo COUNT
O SQLBindCol define SQL_DESC_COUNT ao valor do argumento ColumnNumber apenas quando este aumentaria o valor de SQL_DESC_COUNT. Se o valor no argumento TargetValuePtr for um ponteiro nulo e o valor no argumento ColumnNumber for igual a SQL_DESC_COUNT (isto é, ao desligar a coluna com limite mais alto), então SQL_DESC_COUNT é definido para o número da coluna com limite mais alto restante.
Avisos relativos a SQL_DEFAULT
Para recuperar com sucesso os dados da coluna, a aplicação deve determinar corretamente o comprimento e o ponto de partida dos dados no buffer da aplicação. Quando a aplicação especifica um TargetType explícito, os equívocos da aplicação são facilmente detetados. No entanto, quando a aplicação especifica um TargetType de SQL_DEFAULT, o SQLBindCol pode ser aplicado a uma coluna de um tipo de dado diferente daquele pretendido pela aplicação, seja por alterações nos metadados ou aplicando o código a uma coluna diferente. Neste caso, a aplicação pode nem sempre determinar o início ou o comprimento dos dados da coluna obtidos. Isto pode levar a erros de dados não reportados ou violações de memória.
Exemplo de código
No exemplo seguinte, uma aplicação executa uma instrução SELECT na tabela Clientes para devolver um conjunto de resultados dos IDs de clientes, nomes e números de telefone, ordenados por nome. Depois, chama SQLBindCol para vincular as colunas de dados a buffers locais. Finalmente, a aplicação recolhe cada linha de dados com SQLFetch e imprime o nome, ID e número de telefone de cada cliente.
Para mais exemplos de código, veja Função SQLBulkOperations, Função SQLColumns, Função SQLFetchScroll e Função 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);
}
}
Veja também, Exemplo de Programa ODBC.
Funções relacionadas
| Para obter informações sobre | Veja |
|---|---|
| Devolver informação sobre uma coluna num conjunto de resultados | Função SQLDescribeCol |
| Buscar um bloco de dados ou percorrer um conjunto de resultados | Função SQLFetchScroll |
| Obtenção de várias linhas de dados | Função SQLFetch |
| Libertação de buffers de colunas na instrução | Função SQLFreeStmt |
| Buscar parte ou a totalidade de uma coluna de dados | Função SQLGetData |
| Devolvendo o número de colunas do conjunto de resultados | Função SQLNumResultCols |