SQLBindCol (función)

Conformidad
Versión introducida: Cumplimiento de estándares ODBC 1.0: ISO 92

Resumen
SQLBindCol enlaza los búferes de datos de la aplicación a las columnas del conjunto de resultados.

Sintaxis

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

Argumentos

StatementHandle
[Entrada] Identificador de instrucción.

ColumnNumber
[Entrada] Número de la columna del conjunto de resultados que se va a enlazar. Las columnas se numeran en orden de columna creciente a partir de 0, donde la columna 0 es la columna de marcador. Si no se usan marcadores , es decir, el atributo de instrucción SQL_ATTR_USE_BOOKMARKS se establece en SQL_UB_OFF ; los números de columna comienzan en 1.

TargetType
[Entrada] Identificador del tipo de datos C del búfer *TargetValuePtr . Cuando se recuperan datos del origen de datos con SQLFetch, SQLFetchScroll, SQLBulkOperations o SQLSetPos, el controlador convierte los datos en este tipo; cuando envía datos al origen de datos con SQLBulkOperations o SQLSetPos, el controlador convierte los datos de este tipo. Para obtener una lista de los tipos de datos y identificadores de tipo válidos de C, vea la sección Tipos de datos de C en el Apéndice D: Tipos de datos.

Si el argumento TargetType es un tipo de datos interval, la precisión inicial del intervalo predeterminado (2) y la precisión de segundos del intervalo predeterminado (6), como se establece en los campos SQL_DESC_DATETIME_INTERVAL_PRECISION y SQL_DESC_PRECISION de la ARD, respectivamente, se usan para los datos. Si el argumento TargetType es SQL_C_NUMERIC, la precisión predeterminada (definida por el controlador) y la escala predeterminada (0), tal como se establece en los campos SQL_DESC_PRECISION y SQL_DESC_SCALE del ARD, se usan para los datos. Si alguna precisión o escala predeterminada no es adecuada, la aplicación debe establecer explícitamente el campo descriptor adecuado mediante una llamada a SQLSetDescField o SQLSetDescRec.

También puede especificar un tipo de datos de C extendido. Para obtener más información, vea el tema sobre tipos de datos C en ODBC.

TargetValuePtr
[Entrada/salida diferida] Puntero al búfer de datos que se va a enlazar a la columna. SQLFetch y SQLFetchScroll devuelven datos en este búfer. SQLBulkOperations devuelve datos en este búfer cuando operation es SQL_FETCH_BY_BOOKMARK; recupera datos de este búfer cuando operation se SQL_ADD o SQL_UPDATE_BY_BOOKMARK. SQLSetPos devuelve datos en este búfer cuando operation es SQL_REFRESH; recupera datos de este búfer cuando la operación se SQL_UPDATE.

Si TargetValuePtr es un puntero nulo, el controlador desenlace el búfer de datos de la columna. Una aplicación puede desenlazar todas las columnas llamando a SQLFreeStmt con la opción SQL_UNBIND. Una aplicación puede desenlatar el búfer de datos de una columna pero seguir teniendo un búfer de longitud o indicador enlazado para la columna, si el argumento TargetValuePtr de la llamada a SQLBindCol es un puntero nulo, pero el argumento StrLen_or_IndPtr es un valor válido.

BufferLength
[Entrada] Longitud del búfer *TargetValuePtr en bytes.

El controlador usa BufferLength para evitar escribir más allá del final del búfer *TargetValuePtr cuando devuelve datos de longitud variable, como datos binarios o de caracteres. Observe que el controlador cuenta el carácter de terminación null cuando devuelve datos de caracteres a *TargetValuePtr. *TargetValuePtr debe contener espacio para el carácter de terminación NULL o el controlador truncará los datos.

Cuando el controlador devuelve datos de longitud fija, como un entero o una estructura de fecha, el controlador omite BufferLength y supone que el búfer es lo suficientemente grande como para contener los datos. Por lo tanto, es importante que la aplicación asigne un búfer suficientemente grande para los datos de longitud fija o el controlador escribirá más allá del final del búfer.

SQLBindCol devuelve SQLSTATE HY090 (longitud de cadena o búfer no válida) cuando BufferLength es menor que 0, pero no cuando BufferLength es 0. Sin embargo, si TargetType especifica un tipo de carácter, una aplicación no debe establecer BufferLength en 0, ya que los controladores compatibles con la CLI ISO devuelven SQLSTATE HY090 (longitud de búfer o cadena no válida) en ese caso.

StrLen_or_IndPtr
[Entrada/salida diferida] Puntero al búfer de longitud o indicador que se va a enlazar a la columna. SQLFetch y SQLFetchScroll devuelven un valor en este búfer. SQLBulkOperations recupera un valor de este búfer cuando Operation se SQL_ADD, SQL_UPDATE_BY_BOOKMARK o SQL_DELETE_BY_BOOKMARK. SQLBulkOperations devuelve un valor en este búfer cuando operation es SQL_FETCH_BY_BOOKMARK. SQLSetPos devuelve un valor en este búfer cuando operation es SQL_REFRESH; recupera un valor de este búfer cuando operation se SQL_UPDATE.

SQLFetch, SQLFetchScroll, SQLBulkOperations y SQLSetPos pueden devolver los siguientes valores en el búfer de longitud o indicador:

  • Longitud de los datos disponibles para devolver

  • SQL_NO_TOTAL

  • SQL_NULL_DATA

La aplicación puede colocar los siguientes valores en el búfer de longitud o indicador para su uso con SQLBulkOperations o SQLSetPos:

  • Longitud de los datos que se envían

  • SQL_NTS

  • SQL_NULL_DATA

  • SQL_DATA_AT_EXEC

  • Resultado de la macro SQL_LEN_DATA_AT_EXEC

  • SQL_COLUMN_IGNORE

Si el búfer de indicador y el búfer de longitud son búferes independientes, el búfer de indicador solo puede devolver SQL_NULL_DATA, mientras que el búfer de longitud puede devolver todos los demás valores.

Para obtener más información, vea Función SQLBulkOperations, Función SQLFetch, Función SQLSetPos y Uso de valores de longitud/indicador.

Si StrLen_or_IndPtr es un puntero nulo, no se usa ningún valor de longitud o indicador. Se trata de un error al capturar datos y los datos son NULL.

Consulte Información de 64 bits de ODBC, si la aplicación se ejecutará en un sistema operativo de 64 bits.

Devoluciones

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR o SQL_INVALID_HANDLE.

Diagnóstico

Cuando SQLBindCol devuelve SQL_ERROR o SQL_SUCCESS_WITH_INFO, se puede obtener un valor SQLSTATE asociado llamando a SQLGetDiagRec con un HandleType de SQL_HANDLE_STMT y un identificador de StatementHandle. En la tabla siguiente se enumeran los valores SQLSTATE devueltos normalmente por SQLBindCol y se explica cada uno en el contexto de esta función; la notación "(DM)" precede a las descripciones de SQLSTATEs devueltas por el Administrador de controladores. El código de retorno asociado a cada valor SQLSTATE es SQL_ERROR, a menos que se indique lo contrario.

SQLSTATE Error Descripción
01000 Advertencia general Mensaje informativo específico del controlador. (Function devuelve SQL_SUCCESS_WITH_INFO).
07006 Infracción de atributo de tipo de datos restringido (DM) El argumento ColumnNumber era 0 y el argumento TargetType no se SQL_C_BOOKMARK ni SQL_C_VARBOOKMARK.
07009 Índice de descriptor no válido El valor especificado para el argumento ColumnNumber superó el número máximo de columnas del conjunto de resultados.
HY000 Error general Se produjo un error para el que no había ningún SQLSTATE específico y para el que no se definió SQLSTATE específico de la implementación. El mensaje de error devuelto por SQLGetDiagRec en el búfer *MessageText describe el error y su causa.
HY001 Error de asignación de memoria El controlador no pudo asignar memoria necesaria para admitir la ejecución o finalización de la función.
HY003 Tipo de búfer de aplicación no válido El argumento TargetType no era un tipo de datos válido ni SQL_C_DEFAULT.
HY010 Error de secuencia de función (DM) Se llamó a una función de ejecución asincrónica para el identificador de conexión asociado a StatementHandle. Esta función asincrónica todavía se estaba ejecutando cuando se llamó a SQLBindCol .

(DM) SE llamó a SQLExecute, SQLExecDirect o SQLMoreResults para la instrucciónHandle y devolvió SQL_PARAM_DATA_AVAILABLE. Se llamó a esta función antes de recuperar los datos para todos los parámetros transmitidos.

(DM) Se llamó a una función de ejecución asincrónica para statementHandle y todavía se estaba ejecutando cuando se llamó a esta función.

(DM) SE llamó a SQLExecute, SQLExecDirect, SQLBulkOperations o SQLSetPos para la instrucciónHandle y devolvió SQL_NEED_DATA. Se llamó a esta función antes de enviar datos para todos los parámetros o columnas de datos en ejecución.
HY013 Error de administración de memoria No se pudo procesar la llamada de función porque no se pudo acceder a los objetos de memoria subyacentes, posiblemente debido a condiciones de memoria baja.
HY090 Longitud de búfer o cadena no válida (DM) El valor especificado para el argumento BufferLength era menor que 0.

(DM) El controlador era un ODBC 2. x driver, el argumento ColumnNumber se estableció en 0 y el valor especificado para el argumento BufferLength no era igual a 4.
HY117 La conexión se suspende debido a un estado de transacción desconocido. Solo se permiten funciones de desconexión y de solo lectura. (DM) Para obtener más información sobre el estado suspendido, vea Función SQLEndTran.
HYC00 Característica opcional no implementada El controlador o el origen de datos no admiten la conversión especificada por la combinación del argumento TargetType y el tipo de datos SQL específico del controlador de la columna correspondiente.

El argumento ColumnNumber era 0 y el controlador no admite marcadores.

El controlador solo admite ODBC 2. x y el argumento TargetType fue uno de los siguientes:

SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT

y cualquiera de los tipos de datos de intervalo C enumerados en Tipos de datos de C en el Apéndice D: Tipos de datos.

El controlador solo admite versiones ODBC anteriores a la 3.50 y el argumento TargetType se SQL_C_GUID.
HYT01 Se ha agotado el tiempo de espera de la conexión. El período de tiempo de espera de conexión expiró antes de que el origen de datos respondiera a la solicitud. El período de tiempo de espera de conexión se establece a través de SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 El controlador no admite esta función (DM) El controlador asociado a StatementHandle no admite la función .

Comentarios

SQLBindCol se usa para asociar, o enlazar, columnas del conjunto de resultados a búferes de datos y búferes de longitud o indicador en la aplicación. Cuando la aplicación llama a SQLFetch, SQLFetchScroll o SQLSetPos para capturar datos, el controlador devuelve los datos de las columnas enlazadas en los búferes especificados; para obtener más información, vea Función SQLFetch. Cuando la aplicación llama a SQLBulkOperations para actualizar o insertar una fila o SQLSetPos para actualizar una fila, el controlador recupera los datos de las columnas enlazadas de los búferes especificados; para obtener más información, vea Función SQLBulkOperations o Función SQLSetPos. Para obtener más información sobre el enlace, consulte Recuperación de resultados (básico).

Tenga en cuenta que las columnas no tienen que enlazarse para recuperar datos de ellos. Una aplicación también puede llamar a SQLGetData para recuperar datos de columnas. Aunque es posible enlazar algunas columnas de una fila y llamar a SQLGetData para otras, esto está sujeto a algunas restricciones. Para obtener más información, vea SQLGetData.

Enlace, desenlace y reenlazamiento de columnas

Una columna se puede enlazar, desencuadernar o volver a enlazar en cualquier momento, incluso después de que se hayan capturado los datos del conjunto de resultados. El nuevo enlace surte efecto la próxima vez que se llame a una función que usa enlaces. Por ejemplo, supongamos que una aplicación enlaza las columnas de un conjunto de resultados y llama a SQLFetch. El controlador devuelve los datos de los búferes enlazados. Ahora supongamos que la aplicación enlaza las columnas a un conjunto diferente de búferes. El controlador no coloca los datos de la fila recién capturada en los búferes recién enlazados. En su lugar, espera hasta que se vuelva a llamar a SQLFetch y, a continuación, coloque los datos de la siguiente fila en los búferes recién enlazados.

Nota

El atributo de instrucción SQL_ATTR_USE_BOOKMARKS siempre debe establecerse antes de enlazar una columna a la columna 0. Esto no es necesario, pero se recomienda encarecidamente.

Enlazar columnas

Para enlazar una columna, una aplicación llama a SQLBindCol y pasa el número de columna, el tipo, la dirección y la longitud de un búfer de datos y la dirección de un búfer de longitud o indicador. Para obtener información sobre cómo se usan estas direcciones, vea "Direcciones de búfer", más adelante en esta sección. Para obtener más información sobre las columnas de enlace, vea Uso de SQLBindCol.

El uso de estos búferes se aplaza; Es decir, la aplicación los enlaza en SQLBindCol , pero el controlador accede a ellas desde otras funciones, es decir , SQLBulkOperations, SQLFetch, SQLFetchScroll o SQLSetPos. Es responsabilidad de la aplicación asegurarse de que los punteros especificados en SQLBindCol permanezcan válidos siempre que el enlace permanezca en vigor. Si la aplicación permite que estos punteros no sean válidos (por ejemplo, libera un búfer) y, a continuación, llama a una función que espera que sean válidas, las consecuencias no están definidas. Para obtener más información, vea Búferes diferidos.

El enlace permanece en vigor hasta que se reemplaza por un nuevo enlace, la columna no está enlazada o se libera la instrucción .

Desenlace de columnas

Para desenlazar una sola columna, una aplicación llama a SQLBindCol con ColumnNumber establecido en el número de esa columna y TargetValuePtr establecido en un puntero nulo. Si ColumnNumber hace referencia a una columna sin enlazar, SQLBindCol sigue devuelve SQL_SUCCESS.

Para desenlacar todas las columnas, una aplicación llama a SQLFreeStmt con fOption establecido en SQL_UNBIND. Esto también se puede lograr estableciendo el campo SQL_DESC_COUNT del ARD en cero.

Volver a enlazar columnas

Una aplicación puede realizar cualquiera de las dos operaciones para cambiar un enlace:

  • Llame a SQLBindCol para especificar un nuevo enlace para una columna que ya está enlazada. El controlador sobrescribe el enlace antiguo con el nuevo.

  • Especifique un desplazamiento que se va a agregar a la dirección del búfer especificada por la llamada de enlace a SQLBindCol. Para obtener más información, vea la sección siguiente, "Desplazamientos de enlace".

Desplazamientos de enlace

Un desplazamiento de enlace es un valor que se agrega a las direcciones de los búferes de datos y longitud/indicador (como se especifica en el argumento TargetValuePtr y StrLen_or_IndPtr ) antes de que se desreferencian. Cuando se usan desplazamientos, los enlaces son una "plantilla" de cómo se diseñan los búferes de la aplicación y la aplicación puede mover esta "plantilla" a diferentes áreas de memoria cambiando el desplazamiento. Dado que se agrega el mismo desplazamiento a cada dirección de cada enlace, los desplazamientos relativos entre los búferes para columnas diferentes deben ser los mismos dentro de cada conjunto de búferes. Esto siempre es cierto cuando se usa el enlace de fila; la aplicación debe diseñar cuidadosamente sus búferes para que esto sea true cuando se usa el enlace en sentido de columna.

El uso de un desplazamiento de enlace tiene básicamente el mismo efecto que volver a enlazar una columna mediante una llamada a SQLBindCol. La diferencia es que una nueva llamada a SQLBindCol especifica nuevas direcciones para el búfer de datos y el búfer de longitud o indicador, mientras que el uso de un desplazamiento de enlace no cambia las direcciones, sino que solo agrega un desplazamiento a ellas. La aplicación puede especificar un nuevo desplazamiento siempre que quiera y este desplazamiento siempre se agrega a las direcciones enlazadas originalmente. En concreto, si el desplazamiento se establece en 0 o si el atributo de instrucción está establecido en un puntero nulo, el controlador usa las direcciones enlazadas originalmente.

Para especificar un desplazamiento de enlace, la aplicación establece el atributo de instrucción SQL_ATTR_ROW_BIND_OFFSET_PTR en la dirección de un búfer SQLINTEGER. Antes de que la aplicación llame a una función que usa enlaces, coloca un desplazamiento en bytes en este búfer. Para determinar la dirección del búfer que se va a usar, el controlador agrega el desplazamiento a la dirección del enlace. La suma de la dirección y el desplazamiento deben ser una dirección válida, pero la dirección a la que se agrega el desplazamiento no tiene que ser válida. Para obtener más información sobre cómo se usan los desplazamientos de enlace, vea "Direcciones de búfer", más adelante en esta sección.

Enlazar matrices

Si el tamaño del conjunto de filas (el valor del atributo de instrucción SQL_ATTR_ROW_ARRAY_SIZE) es mayor que 1, la aplicación enlaza matrices de búferes en lugar de búferes únicos. Para obtener más información, vea Cursores de bloque.

La aplicación puede enlazar matrices de dos maneras:

  • Enlace una matriz a cada columna. Esto se conoce como enlace de columna porque cada estructura de datos (matriz) contiene datos para una sola columna.

  • Defina una estructura para contener los datos de una fila completa y enlazar una matriz de estas estructuras. Esto se conoce como enlace de fila porque cada estructura de datos contiene los datos de una sola fila.

Cada matriz de búferes debe tener al menos tantos elementos como el tamaño del conjunto de filas.

Nota

Una aplicación debe comprobar que la alineación es válida. Para obtener más información sobre las consideraciones de alineación, consulte Alineación.

El enlace

En el enlace de columnas, la aplicación enlaza matrices de datos y longitud/indicador independientes a cada columna.

Para usar el enlace en orden de columna, la aplicación establece primero el atributo de instrucción SQL_ATTR_ROW_BIND_TYPE en SQL_BIND_BY_COLUMN. (Este es el valor predeterminado). Para cada columna que se va a enlazar, la aplicación realiza los pasos siguientes:

  1. Asigna una matriz de búfer de datos.

  2. Asigna una matriz de búferes de longitud o indicador.

    Nota

    Si la aplicación escribe directamente en descriptores cuando se usa el enlace en modo de columna, se pueden usar matrices independientes para los datos de longitud e indicador.

  3. Llama a SQLBindCol con los argumentos siguientes:

    • TargetType es el tipo de un único elemento de la matriz de búfer de datos.

    • TargetValuePtr es la dirección de la matriz de búfer de datos.

    • BufferLength es el tamaño de un único elemento de la matriz de búfer de datos. El argumento BufferLength se omite cuando los datos son de longitud fija.

    • StrLen_or_IndPtr es la dirección de la matriz de longitud o indicador.

Para obtener más información sobre cómo se usa esta información, vea "Direcciones de búfer", más adelante en esta sección. Para obtener más información sobre el enlace de columnas, vea Enlace de columnas.

El enlace

En el enlace de fila, la aplicación define una estructura que contiene búferes de datos y longitud/indicador para cada columna que se va a enlazar.

Para usar el enlace de fila, la aplicación realiza los pasos siguientes:

  1. Define una estructura para contener una sola fila de datos (incluidos los búferes de datos y longitud/indicador) y asigna una matriz de estas estructuras.

    Nota

    Si la aplicación escribe directamente en descriptores cuando se usa el enlace de fila, se pueden usar campos independientes para los datos de longitud e indicador.

  2. Establece el atributo de instrucción SQL_ATTR_ROW_BIND_TYPE en el tamaño de la estructura que contiene una sola fila de datos o en el tamaño de una instancia de un búfer en el que se enlazarán las columnas de resultados. La longitud debe incluir espacio para todas las columnas enlazadas y cualquier relleno de la estructura o búfer, para asegurarse de que cuando la dirección de una columna enlazada se incremente con la longitud especificada, el resultado apuntará al principio de la misma columna en la fila siguiente. Al usar el operador sizeof en ANSI C, se garantiza este comportamiento.

  3. Llama a SQLBindCol con los argumentos siguientes para cada columna que se va a enlazar:

    • TargetType es el tipo del miembro del búfer de datos que se va a enlazar a la columna.

    • TargetValuePtr es la dirección del miembro del búfer de datos en el primer elemento de matriz.

    • BufferLength es el tamaño del miembro del búfer de datos.

    • StrLen_or_IndPtr es la dirección del miembro de longitud o indicador que se va a enlazar.

Para obtener más información sobre cómo se usa esta información, vea "Direcciones de búfer", más adelante en esta sección. Para obtener más información sobre el enlace de columnas, vea Enlace de fila.

Direcciones de búfer

La dirección del búfer es la dirección real del búfer de datos o longitud o indicador. El controlador calcula la dirección del búfer justo antes de escribir en los búferes (por ejemplo, durante el tiempo de captura). Se calcula a partir de la fórmula siguiente, que usa las direcciones especificadas en los argumentos TargetValuePtr y StrLen_or_IndPtr , el desplazamiento de enlace y el número de fila:

Dirección + enlazada Desplazamiento de enlace + ((Número de fila - 1) x Tamaño del elemento)

donde las variables de la fórmula se definen como se describe en la tabla siguiente.

Variable Descripción
Dirección enlazada En el caso de los búferes de datos, la dirección especificada con el argumento TargetValuePtr en SQLBindCol.

Para los búferes de longitud o indicador, la dirección especificada con el argumento StrLen_or_IndPtr en SQLBindCol. Para obtener más información, vea "Comentarios adicionales" en la sección "Descriptores y SQLBindCol".

Si la dirección enlazada es 0, no se devuelve ningún valor de datos, incluso si la dirección calculada por la fórmula anterior no es cero.
Desplazamiento de enlace Si se usa el enlace de fila, el valor almacenado en la dirección especificada con el atributo de instrucción SQL_ATTR_ROW_BIND_OFFSET_PTR.

Si se usa el enlace en orden de columna o si el valor del atributo de instrucción SQL_ATTR_ROW_BIND_OFFSET_PTR es un puntero nulo, El desplazamiento de enlace es 0.
Row Number Número basado en 1 de la fila del conjunto de filas. Para las capturas de una sola fila, que son el valor predeterminado, es 1.
Tamaño del elemento Tamaño de un elemento de la matriz enlazada.

Si se usa el enlace de columnas, se trata de sizeof(SQLINTEGER) para los búferes de longitud o indicador. En el caso de los búferes de datos, es el valor del argumento BufferLength en SQLBindCol si el tipo de datos es de longitud variable y el tamaño del tipo de datos si el tipo de datos es de longitud fija.

Si se usa el enlace de fila, este es el valor del atributo de instrucción SQL_ATTR_ROW_BIND_TYPE para los búferes de datos y longitud/indicador.

Descriptores y SQLBindCol

En las secciones siguientes se describe cómo INTERACTÚA SQLBindCol con los descriptores.

Precaución

Llamar a SQLBindCol para una instrucción puede afectar a otras instrucciones. Esto ocurre cuando el ARD asociado a la instrucción se asigna explícitamente y también está asociado a otras instrucciones. Dado que SQLBindCol modifica el descriptor, las modificaciones se aplican a todas las instrucciones con las que está asociado este descriptor. Si no es el comportamiento necesario, la aplicación debe desasociar este descriptor de las demás instrucciones antes de llamar a SQLBindCol.

Asignaciones de argumentos

Conceptualmente, SQLBindCol realiza los pasos siguientes en secuencia:

  1. Llama a SQLGetStmtAttr para obtener el identificador ARD.

  2. Llama a SQLGetDescField para obtener el campo de SQL_DESC_COUNT de este descriptor y, si el valor del argumento ColumnNumber supera el valor de SQL_DESC_COUNT, llama a SQLSetDescField para aumentar el valor de SQL_DESC_COUNT a ColumnNumber.

  3. Llama a SQLSetDescField varias veces para asignar valores a los campos siguientes de ARD:

    • Establece SQL_DESC_TYPE y SQL_DESC_CONCISE_TYPE en el valor de TargetType, salvo que si TargetType es uno de los identificadores concisos de un subtipo datetime o interval, establece SQL_DESC_TYPE en SQL_DATETIME o SQL_INTERVAL, respectivamente; establece SQL_DESC_CONCISE_TYPE en el identificador conciso; y establece SQL_DESC_DATETIME_INTERVAL_CODE en el subcódigo datetime o interval correspondiente.

    • Establece uno o varios SQL_DESC_LENGTH, SQL_DESC_PRECISION, SQL_DESC_SCALE y SQL_DESC_DATETIME_INTERVAL_PRECISION, según corresponda para TargetType.

    • Establece el campo SQL_DESC_OCTET_LENGTH en el valor de BufferLength.

    • Establece el campo SQL_DESC_DATA_PTR en el valor de TargetValuePtr.

    • Establece el campo SQL_DESC_INDICATOR_PTR en el valor de StrLen_or_IndPtr. (Vea el párrafo siguiente).

    • Establece el campo SQL_DESC_OCTET_LENGTH_PTR en el valor de StrLen_or_IndPtr. (Vea el párrafo siguiente).

La variable a la que hace referencia el argumento StrLen_or_IndPtr se usa para la información de indicador y longitud. Si una captura encuentra un valor NULL para la columna, almacena SQL_NULL_DATA en esta variable; de lo contrario, almacena la longitud de los datos en esta variable. Pasar un puntero nulo como StrLen_or_IndPtr impide que la operación de captura devuelva la longitud de los datos, pero hace que se produzca un error en la captura si encuentra un valor NULL y no tiene ninguna manera de devolver SQL_NULL_DATA.

Si se produce un error en la llamada a SQLBindCol , el contenido de los campos descriptores que habría establecido en ARD no está definido y el valor del campo SQL_DESC_COUNT del ARD no cambia.

Restablecimiento implícito del campo COUNT

SQLBindCol establece SQL_DESC_COUNT en el valor del argumento ColumnNumber solo cuando esto aumentaría el valor de SQL_DESC_COUNT. Si el valor del argumento TargetValuePtr es un puntero nulo y el valor del argumento ColumnNumber es igual a SQL_DESC_COUNT (es decir, al desenlace la columna enlazada más alta), SQL_DESC_COUNT se establece en el número de la columna enlazada restante más alta.

Precauciones relacionadas con SQL_DEFAULT

Para recuperar correctamente los datos de columna, la aplicación debe determinar correctamente la longitud y el punto inicial de los datos en el búfer de la aplicación. Cuando la aplicación especifica un TargetType explícito, las ideas erróneas de la aplicación se detectan fácilmente. Sin embargo, cuando la aplicación especifica un TargetType de SQL_DEFAULT, SQLBindCol se puede aplicar a una columna de un tipo de datos diferente del previsto por la aplicación, ya sea desde cambios a los metadatos o aplicando el código a otra columna. En este caso, la aplicación no siempre puede determinar el inicio o la longitud de los datos de columna capturados. Esto puede provocar errores de datos no notificados o infracciones de memoria.

Ejemplo de código

En el ejemplo siguiente, una aplicación ejecuta una instrucción SELECT en la tabla Customers para devolver un conjunto de resultados de los identificadores, nombres y números de teléfono del cliente, ordenados por nombre. A continuación, llama a SQLBindCol para enlazar las columnas de datos a búferes locales. Por último, la aplicación captura cada fila de datos con SQLFetch e imprime el nombre, el identificador y el número de teléfono de cada cliente.

Para obtener más ejemplos de código, vea Función SQLBulkOperations, Función SQLColumns, Función SQLFetchScroll y Función 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);  
   }  
}  

Consulte también El programa ODBC de ejemplo.

Para información acerca de Vea
Devolver información sobre una columna en un conjunto de resultados SQLDescribeCol (función)
Capturar un bloque de datos o desplazarse por un conjunto de resultados Función SQLFetchScroll
Captura de varias filas de datos Función SQLFetch
Liberar búferes de columna en la instrucción Función SQLFreeStmt
Capturar parte o toda una columna de datos Función SQLGetData
Devolver el número de columnas del conjunto de resultados SQLNumResultCols (función)

Consulte también

Referencia de API ODBC
Archivos de encabezado de ODBC