Datos de tipo Long y SQLSetPos y SQLBulkOperations

Como sucede con los parámetros de las instrucciones SQL, se pueden enviar datos largos al actualizar filas con SQLBulkOperations o SQLSetPos o al insertar filas con SQLBulkOperations. Los datos se envían en partes, con varias llamadas a SQLPutData. Las columnas para las que se envían datos durante la ejecución se conocen como columnas de datos en el momento de ejecución.

Nota:

En realidad, una aplicación puede enviar cualquier tipo de datos en tiempo de ejecución con SQLPutData, aunque solo se pueden enviar datos binarios y de caracteres en partes. Sin embargo, si los datos son lo suficientemente pequeños como para caber en un solo búfer, por lo general no hay ninguna razón para usar SQLPutData. Es mucho más fácil enlazar el búfer y permitir que el controlador recupere los datos de este.

Dado que las columnas de datos largos normalmente no están enlazadas, la aplicación debe enlazar la columna antes de llamar a SQLBulkOperations o SQLSetPos y desenlazarla después de llamar a SQLBulkOperations o SQLSetPos. La columna debe estar enalzada porque SQLBulkOperations o SQLSetPos solo funcionan en columnas enlazadas, y debe estar desenlazada para que SQLGetData pueda usarse para recuperar datos de la columna.

Para enviar datos en tiempo de ejecución, la aplicación hace lo siguiente:

  1. Coloca un valor de 32 bits en el búfer del conjunto de filas en lugar de un valor de datos. Este valor se devolverá a la aplicación más adelante, por lo que la aplicación debe establecerlo en un valor significativo, como el número de la columna o el identificador de un archivo que contiene datos.

  2. Establece el valor del búfer de longitud o indicador en el resultado de la macro SQL_LEN_DATA_AT_EXEC(length). Este valor indica al controlador que los datos del parámetro se enviarán con SQLPutData. El valor de longitud se usa al enviar datos largos a un origen de datos que necesita saber cuántos bytes de datos largos se enviarán para que pueda asignar previamente espacio. Para determinar si un origen de datos necesita este valor, la aplicación llama a SQLGetInfo con la opción SQL_NEED_LONG_DATA_LEN. Todos los controladores deben admitir esta macro; si el origen de datos no requiere la longitud de bytes, el controlador puede ignorarlo.

  3. Llama a SQLBulkOperations o SQLSetPos. El controlador detecta que un búfer de longitud o indicador contiene el resultado de la macro SQL_LEN_DATA_AT_EXEC(length) y devuelve SQL_NEED_DATA como valor devuelto de la función.

  4. Llama a SQLParamData en respuesta al valor devuelto SQL_NEED_DATA. Si es necesario enviar datos largos, SQLParamData devuelve SQL_NEED_DATA. En el búfer al que apunta el argumento ValuePtrPtr, el controlador devuelve el valor único que la aplicación colocó en el búfer del conjunto de filas. Si hay más de una columna de datos en el momento de ejecución, la aplicación usa este valor para determinar para qué columna enviar datos; no es necesario que el controlador solicite datos de las columnas de datos en el momento de ejecución en un orden determinado.

  5. Llama a SQLPutData para enviar los datos de columna al controlador. Si los datos de columna no caben en un único búfer, como suele ocurrir con los datos largos, la aplicación llama a SQLPutData repetidamente para enviar los datos en partes; el controlador y el origen de datos se deberán encargar de volver a ensamblar los datos. Si la aplicación pasa datos de cadena terminadas en NULL, el controlador o el origen de datos deben quitar el carácter de terminación NULL como parte del proceso de reensamblaje.

  6. Llama a SQLParamData de nuevo para indicar que ha enviado todos los datos de la columna. Si hay columnas de datos en el momento de ejecución para las que no se han enviado datos, el controlador devuelve SQL_NEED_DATA y el valor único de la siguiente columna de datos en el momento de ejecución; la aplicación vuelve al paso 5. Si se han enviado datos para todas las columnas de datos en el momento de ejecución, los datos de la fila se envían al origen de datos. A continuación, SQLParamData devuelve SQL_SUCCESS o SQL_SUCCESS_WITH_INFO y puede devolver cualquier SQLSTATE que SQLBulkOperations o SQLSetPos pueda devolver.

Después de que SQLBulkOperations o SQLSetPos devuelvan SQL_NEED_DATA y antes de que los datos se hayan enviado por completo para la última columna de datos en el momento de ejecución, la instrucción se encuentra en estado Se necesitan datos. En este estado, la aplicación solo puede llamar a SQLPutData, SQLParamData, SQLCancel, SQLGetDiagField o SQLGetDiagRec; todas las demás funciones devuelven SQLSTATE HY010 (error de secuencia de funciones). Al llamar a SQLCancel, se cancela la ejecución de la instrucción y se devuelve a su estado anterior. Para obtener más información, consulte Anexo B: Tablas de transición de estado ODBC.