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
[输入]指向包含参数或列的实际数据的缓冲区的指针。 对于参数数据) ,数据必须位于 SQLBindParameter (的 ValueType 参数中指定的 C 数据类型,或列数据) 的 SQLBindCol (TargetType 参数。

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 缓冲区的大小是使用 ValueTypeTargetType 指定的 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时,可以通过调用 SQLGetDiagRec 并使用 handleType SQL_HANDLE_STMT 和 Handle ofStatementHandle 来获取关联的 SQLSTATE 值。 下表列出了 SQLPutData 通常返回的 SQLSTATE 值,并对此函数的上下文中的每个值进行了说明:表示法“ (DM) ”位于驱动程序管理器返回的 SQLSTATE 说明之前。 与每个 SQLSTATE 值关联的返回代码SQL_ERROR,除非另有说明。

SQLSTATE 错误 说明
01000 常规警告 特定于驱动程序的信息性消息。 (函数返回 SQL_SUCCESS_WITH_INFO.)
01004 字符串数据,右截断 为输出参数返回的字符串或二进制数据导致截断非空字符或非 NULL 二进制数据。 如果它是字符串值,则它被右截断。 (函数返回 SQL_SUCCESS_WITH_INFO.)
07006 受限数据类型属性冲突 无法将绑定参数的 SQLBindParameter 中的 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参数指定的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。 SQLGetDiagRec*MessageText 缓冲区中返回的错误消息描述了错误及其原因。
HY001 内存分配错误 驱动程序无法分配支持执行或完成函数所需的内存。
HY008 操作已取消 已为 StatementHandle 启用异步处理。 调用了函数,在它完成执行之前,在 StatementHandle 上调用了 SQLCancel 或 SQLCancelHandle 然后,在 StatementHandle 上再次调用函数。

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

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

(DM) SQLExecuteSQLExecDirectSQLMoreResults 已为 StatementHandle 调用并返回SQL_PARAM_DATA_AVAILABLE。 此函数是在检索所有流参数的数据之前调用的。

(DM) 为 StatementHandle 调用了异步执行的函数, (不是此函数) ,在调用此函数时仍在执行。
HY013 内存管理错误 无法处理函数调用,因为无法访问基础内存对象,可能是由于内存不足。
HY019 分片发送的非字符和非二进制数据 为参数或列调用了多次 SQLPutData,它不用于将字符 C 数据发送到具有字符、二进制或数据源特定数据类型的列,也不用于将二进制 C 数据发送到具有字符、二进制或数据源特定数据类型的列。
HY020 尝试连接 null 值 SQLPutData 自返回SQL_NEED_DATA调用以来多次调用,在这些调用之一中, StrLen_or_Ind 参数包含SQL_NULL_DATA或SQL_DEFAULT_PARAM。
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,以执行 sqlExecute 或 SQLExecDirect (sqlExecuteSQLExecDirect) 语句。 如果在为使用 SQLBulkOperations 更新或添加的列发送数据或使用 SQLSetPos 更新时调用它,它可以返回可由 SQLBulkOperationsSQLSetPos 返回的任何 SQLSTATE。

注释

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

当应用程序调用 SQLParamData 来确定它应发送哪些数据时,驱动程序将返回一个指示符,应用程序可以使用该指示器来确定要发送的参数数据或列数据可在何处找到。 它还返回SQL_NEED_DATA,这是应用程序应调用 SQLPutData 以发送数据的指示符。 在 SQLPutDataDataPtr 参数中,应用程序将指针传递到包含参数或列的实际数据的缓冲区。

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

有关如何在语句执行时传递执行时数据参数数据的详细信息,请参阅 SQLBindParameter 中的“传递参数值”和 发送长数据。 有关如何更新或添加执行时数据列数据的详细信息,请参阅 SQLSetPos 中的“使用 SQLSetPos”部分、SQLBulkOperations 中的“使用书签执行批量汇报”以及长数据、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 头文件