SQLPutData 函数

一致性
引入的版本:ODBC 1.0 标准符合性:ISO 92

总结
SQLPutData 允许应用程序在语句执行时向驱动程序发送参数或列的数据。 此函数可用于将部分中的字符或二进制数据值发送到具有字符、二进制或数据源特定数据类型的列(例如,SQL_LONGVARBINARY或SQL_LONGVARCHAR类型的参数)。 SQLPutData 支持绑定到 Unicode C 数据类型,即使基础驱动程序不支持 Unicode 数据。

语法

  
SQLRETURN SQLPutData(  
      SQLHSTMT     StatementHandle,  
      SQLPOINTER   DataPtr,  
      SQLLEN       StrLen_or_Ind);  

参数

StatementHandle
[输入]语句句柄。

DataPtr
[输入]指向包含参数或列的实际数据的缓冲区的指针。 数据必须位于 SQLBindParameterValueType 参数中指定的 C 数据类型(对于参数数据)或 SQLBindColTargetType 参数(对于列数据)。

StrLen_or_Ind
[输入]*DataPtr 的长度。 指定在调用 SQLPutData 时发送的数据量。 对于给定参数或列的每个调用,数据量可能会有所不同。 除非它满足以下条件之一,否则将忽略StrLen_or_Ind:

  • StrLen_or_Ind 是SQL_NTS、SQL_NULL_DATA或SQL_DEFAULT_PARAM。

  • SQLBindParameterSQLBindCol 中指定的 C 数据类型SQL_C_CHAR或SQL_C_BINARY。

  • C 数据类型SQL_C_DEFAULT,指定 SQL 数据类型的默认 C 数据类型SQL_C_CHAR或SQL_C_BINARY。

对于所有其他类型的 C 数据,如果StrLen_or_Ind未SQL_NULL_DATA或SQL_DEFAULT_PARAM,驱动程序假定 *DataPtr 缓冲区的大小是使用 ValueType 或 TargetType 指定的 C 数据类型的大小,并发送整个数据值。 有关详细信息,请参阅 附录 D:数据类型中的将数据从 C 转换为 SQL 数据类型

返回

SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_STILL_EXECUTING、SQL_ERROR或SQL_INVALID_HANDLE。

诊断

当 SQLPutData 返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,可以通过使用 handleType of SQL_HANDLE_STMT 和 StatementHandle 句柄调用 SQLGetDiagRec 来获取关联的 SQLSTATE 值。 下表列出了 SQLPutData 通常返回的 SQLSTATE 值,并解释此函数上下文中的每个值;表示法“(DM)”位于驱动程序管理器返回的 SQLSTATE 的说明之前。 除非另有说明,否则与每个 SQLSTATE 值关联的返回代码SQL_ERROR。

SQLSTATE 错误 说明
01000 常规警告 特定于驱动程序的信息性消息。 (函数返回SQL_SUCCESS_WITH_INFO。)
01004 字符串数据,右截断 为输出参数返回的字符串或二进制数据导致非空字符或非 NULL 二进制数据的截断。 如果它是字符串值,则将其右截断。 (函数返回SQL_SUCCESS_WITH_INFO。)
07006 受限数据类型属性冲突 无法将绑定参数的 ValueType 参数标识的数据值转换为 SQLBindParameter 中的 ParameterType 参数标识的数据类型。
07S01 默认参数的使用无效 使用 SQLBindParameter 设置的参数值SQL_DEFAULT_PARAM,并且相应的参数没有默认值。
08S01 通信链接失败 驱动程序与驱动程序连接到的数据源之间的通信链接在函数完成处理之前失败。
22001 字符串数据,右截断 将字符或二进制值赋值给列导致非空(字符)或非 null(二进制)字符或字节的截断。

SQLGetInfo 中的SQL_NEED_LONG_DATA_LEN信息类型为“Y”,并且为长参数(数据类型SQL_LONGVARCHAR、SQL_LONGVARBINARY或长数据源特定数据类型)发送的数据多于使用 SQLBindParameter 中的StrLen_or_IndPtr参数指定的数据。

SQLGetInfo 中的SQL_NEED_LONG_DATA_LEN信息类型为“Y”,并且为长列发送了更多数据(数据类型SQL_LONGVARCHAR、SQL_LONGVARBINARY或长数据源特定的数据类型),而不是在与 SQLBulkOperations 一行中添加或更新的数据行中的列相对应的长度缓冲区中指定的数据,或使用 SQLSetPos 进行更新
22003 数值范围之外 为绑定数值参数或列发送的数据导致分配给关联的表列时,将数字的整个部分(而不是小数部分)截断。

返回一个或多个输入/输出或输出参数的数值(作为数字或字符串),会导致截断数字的整个(而不是小数部分)。
22007 日期/时间格式无效 为绑定到日期、时间或时间戳结构的参数或列发送的数据分别是无效的日期、时间或时间戳。

输入/输出或输出参数绑定到日期、时间或时间戳 C 结构,返回的参数中的值分别为无效的日期、时间或时间戳。 (函数返回SQL_SUCCESS_WITH_INFO。)
22008 日期/时间字段溢出 为输入/输出或输出参数计算的日期/时间表达式导致日期、时间或时间戳 C 结构无效。
22012 被零除 为输入/输出或输出参数计算的算术表达式,结果除以零。
22015 间隔字段溢出 为精确数字或间隔列或参数发送到间隔 SQL 数据类型的数据导致有效数字丢失。

为具有多个字段的间隔列或参数发送数据,已转换为数值数据类型,在数值数据类型中没有表示形式。

为列或参数数据发送的数据已分配给间隔 SQL 类型,并且间隔 SQL 类型中没有 C 类型的值表示形式。

为精确数字或间隔 C 列或参数发送到间隔 C 类型的数据导致有效数字丢失。

为列或参数数据发送的数据被分配到间隔 C 结构,并且间隔数据结构中没有数据的表示形式。
22018 强制转换规范的字符值无效 C 类型是精确或近似数字、日期/时间或间隔数据类型;列的 SQL 类型是字符数据类型;和列或参数中的值不是绑定 C 类型的有效文本。

SQL 类型是精确或近似数字、日期/时间或间隔数据类型;C 类型SQL_C_CHAR;和列或参数中的值不是绑定 SQL 类型的有效文本。
HY000 常规错误 发生错误:没有特定的 SQLSTATE,也没有定义特定于实现的 SQLSTATE。 *MessageText 缓冲区中 SQLGetDiagRec 返回的错误消息描述错误及其原因。
HY001 内存分配错误 驱动程序无法分配支持执行或完成函数所需的内存。
HY008 操作已取消 StatementHandle 启用了异步处理。 调用了该函数,在完成执行之前,对 StatementHandle 调用了 SQLCancel 或 SQLCancelHandle。 然后,在 StatementHandle再次调用该函数。

调用了函数,在完成执行之前,SQLCancel 或 SQLCancelHandle 从多线程应用程序中的不同线程调用 StatementHandle
HY009 无效使用 null 指针 (DM) 参数 DataPtr 是空指针, 参数StrLen_or_Ind 不是 0、SQL_DEFAULT_PARAM 或SQL_NULL_DATA。
HY010 函数序列错误 (DM) 上一个函数调用不是对 SQLPutDataSQLParamData调用。

(DM) 为与 StatementHandle 关联的连接句柄调用异步执行函数。 调用 SQLPutData 函数时,此异步函数仍在执行。

(DM) 为 StatementHandle 调用了 SQLExecuteSQLExecDirectSQLMoreResults,并返回了SQL_PARAM_DATA_AVAILABLE。 在检索所有流式处理参数的数据之前调用此函数。

(DM) 为 StatementHandle 调用异步执行函数(而不是此函数),并在调用此函数时仍在执行。
HY013 内存管理错误 无法处理函数调用,因为基础内存对象无法访问,可能是因为内存条件低。
HY019 以片段形式发送的非字符和非二进制数据 针对参数或列多次调用 SQLPutData ,它不用于将字符 C 数据发送到具有字符、二进制或数据源特定数据类型的列,或者将二进制 C 数据发送到具有字符、二进制或数据源特定数据类型的列。
HY020 尝试连接 null 值 自返回SQL_NEED_DATA的调用以及其中一个调用中,StrLen_or_Ind参数包含SQL_NULL_DATA或SQL_DEFAULT_PARAM以来,多次调用 SQLPutData
HY090 字符串或缓冲区长度无效 参数 DataPtr 不是空指针,参数StrLen_or_Ind小于 0,但不等于SQL_NTS或SQL_NULL_DATA。
HY117 连接因未知事务状态而挂起。 仅允许断开连接和只读函数。 (DM) 有关挂起状态的详细信息,请参阅 SQLEndTran 函数
HYT01 超过连接超时时间 在数据源响应请求之前,连接超时期限已过期。 连接超时期限通过 SQLSetConnectAttr 设置,SQL_ATTR_CONNECTION_TIMEOUT。
IM001 驱动程序不支持此函数 (DM) 与 StatementHandle 关联的驱动程序不支持该函数。
IM017 在异步通知模式下禁用轮询 每当使用通知模型时,轮询将被禁用。
IM018 尚未调用 SQLCompleteAsync 来完成此句柄上的上一个异步操作。 如果句柄上的上一个函数调用返回SQL_STILL_EXECUTING并且启用通知模式, 则必须在句柄上调用 SQLCompleteAsync 才能执行后期处理并完成操作。

如果在 为 SQL 语句中的参数发送数据时调用 SQLPutData ,则它可以返回任何 SQLSTATE,该 SQLSTATE 可由调用的函数返回以执行语句(SQLExecuteSQLExecDirect)。 如果在发送更新或添加 SQLBulkOperations 或 SQLSetPos 更新列的数据时调用它,则它可以返回 SQLBulkOperationsSQLSetPos 可以返回的任何 SQLSTATE。

注释

可以调用 SQLPutData 来提供两个用途的数据执行数据:调用 SQLExecuteSQLExecDirect要使用的参数数据,或调用 SQLBulkOperations 或由对 SQLSetPos 的调用更新或添加行时使用的列数据。

当应用程序调用 SQLParamData 来确定它应发送的数据时,驱动程序将返回一个指示器,指示应用程序可用于确定要发送的参数数据或找到列数据的位置。 它还返回SQL_NEED_DATA,这是应用程序应调用 SQLPutData 发送数据的指示器。 在 DataPtr 参数中,应用程序将指针传递给包含参数或列的实际数据的缓冲区。

当驱动程序返回 SQLPutData SQL_SUCCESS时,应用程序会再次调用 SQLParamData如果需要发送更多数据,SQLParamData 将返回SQL_NEED_DATA在这种情况下,应用程序再次调用 SQLPutData 。 如果发送了所有数据,则返回SQL_SUCCESS。 然后,应用程序再次调用 SQLParamData 。 如果驱动程序在 *ValuePtrPtr 中返回SQL_NEED_DATA和另一个指示器,则它需要另一个参数或列的数据,并再次调用 SQLPutData。 如果驱动程序返回SQL_SUCCESS,则已发送所有数据执行数据,并且可以执行 SQL 语句,或者 可以处理 SQLBulkOperationsSQLSetPos 调用。

有关如何在语句执行时传递数据执行参数数据的详细信息,请参阅 SQLBindParameter 中的“传递参数值”和发送长数据。 有关如何更新或添加数据执行列数据的详细信息,请参阅 SQLSetPos 中的“使用 SQLSetPos”部分、SQLBulkOperations 中的“使用书签执行批量更新”以及 Long Data 和 SQLSetPos 和 SQLBulkOperations

注意

应用程序只能在将字符 C 数据发送到具有字符、二进制或数据源特定数据类型的列时,或者将二进制 C 数据发送到具有字符、二进制或数据源特定数据类型的列时,才能使用 SQLPutData 在部件中发送数据。 如果在 任何其他条件下多次调用 SQLPutData ,它将返回SQL_ERROR和 SQLSTATE HY019(以片段形式发送的非字符和非二进制数据)。

示例

以下示例假定数据源名称名为 Test。 关联的数据库应具有可以创建的表,如下所示:

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);  
}  
有关以下内容的信息 请参阅
将缓冲区绑定到参数 SQLBindParameter 函数
取消语句处理 SQLCancel 函数
执行 SQL 语句 SQLExecDirect 函数
执行准备的 SQL 语句 SQLExecute 函数
返回要为其发送数据的下一个参数 SQLParamData 函数

另请参阅

ODBC API 参考
ODBC 头文件