Función SQLPutData
Conformidad
Versión introducida: Cumplimiento de estándares ODBC 1.0: ISO 92
Resumen
SQLPutData permite a una aplicación enviar datos de un parámetro o columna al controlador en tiempo de ejecución de instrucciones. Esta función se puede usar para enviar valores de datos binarios o de caracteres en partes a una columna con un tipo de datos específico del origen de datos, binario o carácter (por ejemplo, parámetros de los tipos de SQL_LONGVARBINARY o SQL_LONGVARCHAR). SQLPutData admite el enlace a un tipo de datos Unicode C, incluso si el controlador subyacente no admite datos Unicode.
Sintaxis
SQLRETURN SQLPutData(
SQLHSTMT StatementHandle,
SQLPOINTER DataPtr,
SQLLEN StrLen_or_Ind);
Argumentos
StatementHandle
[Entrada] Identificador de instrucciones.
DataPtr
[Entrada] Puntero a un búfer que contiene los datos reales del parámetro o columna. Los datos deben estar en el tipo de datos C especificado en el argumento ValueType de SQLBindParameter (para los datos de parámetros) o el argumento TargetType de SQLBindCol (para los datos de columna).
StrLen_or_Ind
[Entrada] Longitud de *DataPtr. Especifica la cantidad de datos enviados en una llamada a SQLPutData. La cantidad de datos puede variar con cada llamada a un parámetro o columna determinado. StrLen_or_Ind se omite a menos que cumpla una de las condiciones siguientes:
StrLen_or_Ind es SQL_NTS, SQL_NULL_DATA o SQL_DEFAULT_PARAM.
El tipo de datos de C especificado en SQLBindParameter o SQLBindCol es SQL_C_CHAR o SQL_C_BINARY.
El tipo de datos de C es SQL_C_DEFAULT y el tipo de datos de C predeterminado para el tipo de datos SQL especificado es SQL_C_CHAR o SQL_C_BINARY.
Para todos los demás tipos de datos de C, si StrLen_or_Ind no es SQL_NULL_DATA o SQL_DEFAULT_PARAM, el controlador asume que el tamaño del búfer *DataPtr es el tamaño del tipo de datos C especificado con ValueType o TargetType y envía el valor de datos completo. Para obtener más información, vea Convertir datos de C a tipos de datos SQL en el Apéndice D: Tipos de datos.
Devoluciones
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR o SQL_INVALID_HANDLE.
Diagnóstico
Cuando SQLPutData 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 SQLPutData 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). |
01004 | Datos de cadena, truncados a la derecha | Los datos binarios o de cadena devueltos para un parámetro de salida provocaron el truncamiento de datos binarios que no son null o caracteres no NULL. Si era un valor de cadena, se truncaba a la derecha. (Function devuelve SQL_SUCCESS_WITH_INFO). |
07006 | Infracción de atributo de tipo de datos restringido | No se pudo convertir el valor de datos identificado por el argumento ValueType en SQLBindParameter para el parámetro enlazado al tipo de datos identificado por el argumento ParameterType en SQLBindParameter. |
07S01 | Uso no válido del parámetro predeterminado | Un valor de parámetro, establecido con SQLBindParameter, se SQL_DEFAULT_PARAM y el parámetro correspondiente no tenía un valor predeterminado. |
08S01 | Error de vínculo de comunicación | Se produjo un error en el vínculo de comunicación entre el controlador y el origen de datos al que se conectó el controlador antes de que la función completara el procesamiento. |
22001 | Datos de cadena, truncamiento derecho | La asignación de un carácter o valor binario a una columna dio como resultado el truncamiento de caracteres o bytes no nulos (binarios). El tipo de información SQL_NEED_LONG_DATA_LEN en SQLGetInfo era "Y" y se enviaron más datos para un parámetro long (el tipo de datos se SQL_LONGVARCHAR, SQL_LONGVARBINARY o un tipo de datos largo específico del origen de datos) que se especificó con el argumento StrLen_or_IndPtr en SQLBindParameter. El tipo de información SQL_NEED_LONG_DATA_LEN en SQLGetInfo era "Y" y se enviaron más datos para una columna larga (el tipo de datos se SQL_LONGVARCHAR, SQL_LONGVARBINARY o un tipo de datos largo específico del origen de datos) que se especificó en el búfer de longitud correspondiente a una columna de una fila de datos que se agregó o actualizó con SQLBulkOperations o se actualizó con SQLSetPos. |
22003 | Valor numérico fuera del intervalo | Los datos enviados para un parámetro numérico enlazado o columna provocaron que toda la parte (en lugar de fraccionaria) del número se truncase cuando se asigne a la columna de tabla asociada. Devolver un valor numérico (como numérico o cadena) para uno o varios parámetros de entrada/salida o salida habrían provocado que toda la parte (en lugar de fraccionaria) del número se truncase. |
22007 | Formato datetime no válido | Los datos enviados para un parámetro o columna enlazados a una estructura de fecha, hora o marca de tiempo fueron, respectivamente, una fecha, hora o marca de tiempo no válidas. Un parámetro de entrada/salida o salida estaba enlazado a una estructura C de fecha, hora o marca de tiempo, y un valor en el parámetro devuelto era, respectivamente, una fecha, hora o marca de tiempo no válidas. (Function devuelve SQL_SUCCESS_WITH_INFO). |
22008 | Desbordamiento de campo datetime | Una expresión datetime calculada para un parámetro de entrada/salida o salida dio lugar a una estructura C de fecha, hora o marca de tiempo que no era válida. |
22012 | División por cero | Una expresión aritmética calculada para un parámetro de entrada/salida o salida dio como resultado la división en cero. |
22015 | Desbordamiento de campo de intervalo | Los datos enviados para una columna o parámetro numérico o de intervalo exacto a un tipo de datos SQL de intervalo provocaron una pérdida de dígitos significativos. Los datos se enviaron para una columna o parámetro de intervalo con más de un campo, se convirtió en un tipo de datos numérico y no tenía ninguna representación en el tipo de datos numérico. Los datos enviados para los datos de columna o parámetro se asignaron a un tipo SQL de intervalo y no había ninguna representación del valor del tipo C en el tipo SQL interval. Los datos enviados para una columna o parámetro numérico o intervalo exacto de C a un tipo de intervalo C provocaron una pérdida de dígitos significativos. Los datos enviados para los datos de columna o parámetro se asignaron a una estructura de intervalo C y no había ninguna representación de los datos en la estructura de datos de intervalo. |
22018 | Valor de carácter no válido para la especificación de conversión | El tipo C era un numérico exacto o aproximado, una fecha y hora o un tipo de datos interval; el tipo SQL de la columna era un tipo de datos de caracteres; y el valor de la columna o parámetro no era un literal válido del tipo de C enlazado. El tipo SQL era un numérico exacto o aproximado, una fecha y hora o un tipo de datos de intervalo; el tipo C se SQL_C_CHAR; y el valor de la columna o parámetro no era un literal válido del tipo SQL enlazado. |
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. |
HY008 | Operación cancelada | El procesamiento asincrónico se ha habilitado para StatementHandle. Se llamó a la función y antes de completar la ejecución, se llamó a SQLCancel o SQLCancelHandle en StatementHandle. A continuación, se llamó a la función de nuevo en StatementHandle. Se llamó a la función y antes de completar la ejecución, se llamó a SQLCancel o SQLCancelHandle en statementHandle desde un subproceso diferente en una aplicación multiproceso. |
HY009 | Uso no válido del puntero nulo | (DM) El argumento DataPtr era un puntero nulo y el argumento StrLen_or_Ind no era 0, SQL_DEFAULT_PARAM o SQL_NULL_DATA. |
HY010 | Error de secuencia de funciones | (DM) La llamada de función anterior no era una llamada a SQLPutData o SQLParamData. (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 la función SQLPutData. (DM) SQLExecute, SQLExecDirect o SQLMoreResults se llamó a para statementHandle 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 que ejecuta de forma asincrónica (no esta) para statementHandle y todavía se estaba ejecutando cuando se llamó a esta función. |
HY013 | Error de administración de memoria | No se pudo procesar la llamada de función porque no se pudo tener acceso a los objetos de memoria subyacentes, posiblemente debido a condiciones de memoria baja. |
HY019 | Datos no binarios y no binarios enviados en partes | SQLPutData se llamó más de una vez para un parámetro o columna, y no se usaba para enviar datos de caracteres C a una columna con un tipo de datos específico del origen de datos o caracteres, binarios o para enviar datos binarios de C a una columna con un carácter, binario o tipo de datos específico del origen de datos. |
HY020 | Intentar concatenar un valor NULL | SQLPutData se llamó más de una vez desde la llamada que devolvió SQL_NEED_DATA y, en una de esas llamadas, el argumento StrLen_or_Ind contenía SQL_NULL_DATA o SQL_DEFAULT_PARAM. |
HY090 | Longitud de búfer o cadena no válida | El argumento DataPtr no era un puntero nulo y el argumento StrLen_or_Ind era menor que 0, pero no igual a SQL_NTS o SQL_NULL_DATA. |
HY117 | La conexión se suspende debido al estado de transacción desconocido. Solo se permiten las funciones de desconexión y solo lectura. | (DM) Para obtener más información sobre el estado suspendido, vea Función SQLEndTran. |
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 . |
IM017 | El sondeo está deshabilitado en modo de notificación asincrónica | Cada vez que se usa el modelo de notificación, el sondeo está deshabilitado. |
IM018 | No se ha llamado a SQLCompleteAsync para completar la operación asincrónica anterior en este identificador. | Si la llamada de función anterior en el identificador devuelve SQL_STILL_EXECUTING y si el modo de notificación está habilitado, se debe llamar a SQLCompleteAsync en el identificador para realizar el procesamiento posterior y completar la operación. |
Si se llama a SQLPutData al enviar datos para un parámetro en una instrucción SQL, puede devolver cualquier SQLSTATE que pueda devolver la función llamada para ejecutar la instrucción (SQLExecute o SQLExecDirect). Si se llama al enviar datos para una columna que se actualiza o se agrega con SQLBulkOperations o se actualiza con SQLSetPos, puede devolver cualquier SQLSTATE que SQLBulkOperations o SQLSetPos pueda devolver.
Comentarios
Se puede llamar a SQLPutData para proporcionar datos en ejecución para dos usos: datos de parámetros que se usarán en una llamada a SQLExecute o SQLExecDirect, o datos de columna que se usarán cuando una fila se actualiza o agrega mediante una llamada a SQLBulkOperations o se actualiza mediante una llamada a SQLSetPos.
Cuando una aplicación llama a SQLParamData para determinar qué datos debe enviar, el controlador devuelve un indicador que la aplicación puede usar para determinar qué datos de parámetro enviar o dónde se pueden encontrar los datos de columna. También devuelve SQL_NEED_DATA, que es un indicador de la aplicación que debe llamar a SQLPutData para enviar los datos. En el argumento DataPtr a SQLPutData, la aplicación pasa un puntero al búfer que contiene los datos reales del parámetro o columna.
Cuando el controlador devuelve SQL_SUCCESS para SQLPutData, la aplicación vuelve a llamar a SQLParamData . SQLParamData devuelve SQL_NEED_DATA si es necesario enviar más datos, en cuyo caso la aplicación llama a SQLPutData de nuevo. Devuelve SQL_SUCCESS si se han enviado todos los datos en ejecución. A continuación, la aplicación llama a SQLParamData de nuevo. Si el controlador devuelve SQL_NEED_DATA y otro indicador en *ValuePtrPtr, requiere datos para otro parámetro o columna y se vuelve a llamar a SQLPutData . Si el controlador devuelve SQL_SUCCESS, se han enviado todos los datos en ejecución y se puede ejecutar la instrucción SQL o se puede procesar la llamada SQLBulkOperations o SQLSetPos .
Para obtener más información sobre cómo se pasan los datos de parámetros de ejecución en tiempo de ejecución de instrucciones, vea "Pasar valores de parámetro" en SQLBindParameter y Enviar datos largos. Para obtener más información sobre cómo se actualizan o agregan datos de columna de datos en ejecución, vea la sección "Using SQLSetPos" en SQLSetPos, "Performing Bulk Updates Using Bookmarks" (Realizar actualizaciones masivas mediante marcadores) en SQLBulkOperations y Long Data y SQLSetPos y SQLBulkOperations.
Nota:
Una aplicación puede usar SQLPutData para enviar datos en partes solo al enviar datos de caracteres C a una columna con un tipo de datos específico de origen de datos, binario o de caracteres o al enviar datos binarios de C a una columna con un tipo de datos específico del origen de datos, binarios o caracteres. Si se llama a SQLPutData más de una vez en cualquier otra condición, devuelve SQL_ERROR y SQLSTATE HY019 (datos no de caracteres y no binarios enviados en partes).
Ejemplo
En el ejemplo siguiente se presupone un nombre de origen de datos denominado Test. La base de datos asociada debe tener una tabla que puede crear, como se indica a continuación:
CREATE TABLE emp4 (NAME char(30), AGE int, BIRTHDAY datetime, Memo1 text)
// SQLPutData.cpp
// compile with: odbc32.lib user32.lib
#include <stdio.h>
#include <windows.h>
#include <sqlext.h>
#include <odbcss.h>
#define TEXTSIZE 12000
#define MAXBUFLEN 256
SQLHENV henv = SQL_NULL_HENV;
SQLHDBC hdbc1 = SQL_NULL_HDBC;
SQLHSTMT hstmt1 = SQL_NULL_HSTMT;
void Cleanup() {
if (hstmt1 != SQL_NULL_HSTMT)
SQLFreeHandle(SQL_HANDLE_STMT, hstmt1);
if (hdbc1 != SQL_NULL_HDBC) {
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
}
if (henv != SQL_NULL_HENV)
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
int main() {
RETCODE retcode;
// SQLBindParameter variables.
SQLLEN cbTextSize, lbytes;
// SQLParamData variable.
PTR pParmID;
// SQLPutData variables.
UCHAR Data[] =
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz";
SDWORD cbBatch = (SDWORD)sizeof(Data) - 1;
// Allocate the ODBC environment and save handle.
retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLAllocHandle(Env) Failed\n\n");
Cleanup();
return(9);
}
// Notify ODBC that this is an ODBC 3.0 app.
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLSetEnvAttr(ODBC version) Failed\n\n");
Cleanup();
return(9);
}
// Allocate ODBC connection handle and connect.
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLAllocHandle(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
// Sample uses Integrated Security, create SQL Server DSN using Windows NT authentication.
retcode = SQLConnect(hdbc1, (UCHAR*)"Test", SQL_NTS, (UCHAR*)"",SQL_NTS, (UCHAR*)"", SQL_NTS);
if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
printf("SQLConnect() Failed\n\n");
Cleanup();
return(9);
}
// Allocate statement handle.
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt1);
if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
printf("SQLAllocHandle(hstmt1) Failed\n\n");
Cleanup();
return(9);
}
// Set parameters based on total data to send.
lbytes = (SDWORD)TEXTSIZE;
cbTextSize = SQL_LEN_DATA_AT_EXEC(lbytes);
// Bind the parameter marker.
retcode = SQLBindParameter (hstmt1, // hstmt
1, // ipar
SQL_PARAM_INPUT, // fParamType
SQL_C_CHAR, // fCType
SQL_LONGVARCHAR, // FSqlType
lbytes, // cbColDef
0, // ibScale
(VOID *)1, // rgbValue
0, // cbValueMax
&cbTextSize); // pcbValue
if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
printf("SQLBindParameter Failed\n\n");
Cleanup();
return(9);
}
// Execute the command.
retcode =
SQLExecDirect(hstmt1, (UCHAR*)"INSERT INTO emp4 VALUES('Paul Borm', 46,'1950-11-12 00:00:00', ?)", SQL_NTS);
if ( (retcode != SQL_SUCCESS) && (retcode != SQL_NEED_DATA) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
printf("SQLExecDirect Failed\n\n");
Cleanup();
return(9);
}
// Check to see if NEED_DATA; if yes, use SQLPutData.
retcode = SQLParamData(hstmt1, &pParmID);
if (retcode == SQL_NEED_DATA) {
while (lbytes > cbBatch) {
SQLPutData(hstmt1, Data, cbBatch);
lbytes -= cbBatch;
}
// Put final batch.
retcode = SQLPutData(hstmt1, Data, lbytes);
}
if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
printf("SQLParamData Failed\n\n");
Cleanup();
return(9);
}
// Make final SQLParamData call.
retcode = SQLParamData(hstmt1, &pParmID);
if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
printf("Final SQLParamData Failed\n\n");
Cleanup();
return(9);
}
// Clean up.
SQLFreeHandle(SQL_HANDLE_STMT, hstmt1);
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
Funciones relacionadas
Para obtener información sobre | Vea |
---|---|
Enlace de un búfer a un parámetro | Función SQLBindParameter |
Cancelación del procesamiento de instrucciones | Función SQLCancel |
Ejecución de una instrucción SQL | Función SQLExecDirect |
Ejecución de una instrucción SQL preparada | Función SQLExecute |
Devolver el siguiente parámetro para enviar datos | Función SQLParamData |