bcp_bind

适用于:SQL Server Azure SQL 数据库 Azure SQL 托管实例 Azure Synapse Analytics Analytics 平台系统(PDW)

将数据从程序变量绑定到表列,以便批量复制到 SQL Server。

语法

  
RETCODE bcp_bind (  
        HDBC hdbc,
        LPCBYTE pData,  
        INT cbIndicator,  
        DBINT cbData,  
        LPCBYTE pTerm,  
        INT cbTerm,  
        INT eDataType,  
        INT idxServerCol);  

参数

hdbc
已启用大容量复制的 ODBC 连接句柄。

pData
指向已复制数据的指针。 如果 eDataType 为 SQLTEXT、SQLNTEXT、SQLXML、SQLUDT、SQLCHARACTER、SQLVARCHAR、SQLVARBINARY、SQLBINARY、SQLNCHAR 或 SQLIMAGE,pData 可以为 NULL。 NULL pData 指示使用 bcp_moretext 以区块为单位将长数据值发送到 SQL Server。 如果用户与用户绑定字段对应的列为 BLOB 列,则用户应仅将 pData 设置为 NULL,否则bcp_bind将失败。

如果数据中存在指示符,这些指示符则在内存中直接显示在数据之前。 在此示例中,pData 参数指向指示器变量,而指示器的宽度(cbIndicator 参数)则通过大容量复制来正确处理用户数据。

cbIndicator
列数据的长度或 Null 指示符的长度(以字节为单位)。 有效指示器长度值是 0(不使用任何指示器时)、1、2、4 或 8。 指示符在内存中直接显示在任何数据之前。 例如,以下结构类型定义可用于使用大容量复制将整数值插入 SQL Server 表中:

typedef struct tagBCPBOUNDINT  
    {  
    int iIndicator;  
    int Value;  
    } BCPBOUNDINT;  

在本示例中, pData 参数将设置为结构的声明实例的地址,即 BCPBOUNDINT iIndicator 结构成员的地址。 cbIndicator 参数将设置为整数(sizeof(int)的大小,cbData 参数将再次设置为整数(sizeof(int)的大小。 若要将行批量复制到包含绑定列的 NULL 值的服务器,实例的 iIndicator 成员的值应设置为SQL_NULL_DATA。

cbData
程序变量中数据的字节计数,不包括任何长度/Null 指示符或终止符的长度。

cbData 设置为SQL_NULL_DATA表示复制到服务器的所有行都包含列的 NULL 值。

cbData 设置为SQL_VARLEN_DATA表示系统将使用字符串终止符或其他方法来确定复制的数据长度。

对于固定长度的数据类型(如整数),该数据类型指示系统中的数据的长度。 因此,对于固定长度数据类型, cbData 可以安全地SQL_VARLEN_DATA或数据的长度。

对于 SQL Server 字符和二进制数据类型, cbData 可以SQL_VARLEN_DATA、SQL_NULL_DATA、某些正值或 0。 如果 cbData 是SQL_VARLEN_DATA,则系统使用长度/null 指示器(如果存在)或终止符序列来确定数据的长度。 如果同时提供指示符和终止符序列,系统则使用二者中可导致数据复制量最少的那一个。 如果 cbData 是SQL_VARLEN_DATA,则列的数据类型为 SQL Server 字符或二进制类型,并且未指定长度指示器或终止符序列,系统将返回错误消息。

如果 cbData 为 0 或正值,则系统会使用 cbData 作为数据长度。 但是,如果除了正 cbData 值外,还提供了长度指示器或终止符序列,则系统通过使用导致复制的数据量最少的方法来确定数据长度。

cbData 参数值表示数据的字节数。 如果字符数据由 Unicode 宽字符表示,则正 cbData 参数值表示字符数乘以每个字符的大小(以字节为单位)。

pTerm
指向标记该程序变量末尾的字节模式(如果有)的指针。 例如,ANSI 和 MBCS C 字符串通常采用 1 个字节的终止符 (\0)。

如果变量没有终止符,请将 pTerm 设置为 NULL。

您可以使用空字符串 ("") 将 C Null 终止符指定为程序变量终止符。 由于以 null 结尾的空字符串构成单个字节(终止符字节本身),因此将 cbTerm 设置为 1。 例如,若要指示 szName 中的字符串以 null 结尾,并且应使用终止符来指示长度:

bcp_bind(hdbc, szName, 0,  
   SQL_VARLEN_DATA, "", 1,  
   SQLCHARACTER, 2)  

此示例的非确定形式可能指示将 15 个字符从 szName 变量复制到绑定表的第二列:

bcp_bind(hdbc, szName, 0, 15,
   NULL, 0, SQLCHARACTER, 2)  

大容量复制 API 根据需要执行 Unicode 到 MBCS 的字符转换。 确保终止符字节字符串和字节字符串的长度均已正确设置。 例如,若要指示 szName 中的字符串是 Unicode 宽字符字符串,由 Unicode null 终止符值终止:

bcp_bind(hdbc, szName, 0,
   SQL_VARLEN_DATA, L"",  
   sizeof(WCHAR), SQLNCHAR, 2)  

如果绑定的 SQL Server 列是宽字符,则不会对 bcp_sendrow执行转换。 如果 SQL Server 列是 MBCS 字符类型,则会在将数据发送到 SQL Server 时执行宽字符到多字节字符转换。

cbTerm
存在于程序变量的终止符(如果有)中的字节计数。 如果变量没有终止符,请将 cbTerm 设置为 0。

eDataType 是程序变量的 C 数据类型。 程序变量中的数据转换为数据库列的类型。 如果该参数为 0,则不执行转换。

eDataType 参数由 sqlncli.h 中的 SQL Server 数据类型标记(而不是 ODBC C 数据类型枚举器)枚举。 例如,可以使用特定于 SQL Server 的类型SQLINT2指定双字节整数 ODBC 类型SQL_C_SHORT。

SQL Server 2005 (9.x) 引入了对 eDataType 参数中 SQLXML 和 SQLUDT 数据类型令牌的支持。

下表列出了有效的枚举数据类型以及相应的 ODBC C 数据类型。

eDataType C 类型
SQLTEXT char *
SQLNTEXT wchar_t *
SQLCHARACTER char *
SQLBIGCHAR char *
SQLVARCHAR char *
SQLBIGVARCHAR char *
SQLNCHAR wchar_t *
SQLNVARCHAR wchar_t *
SQLBINARY unsigned char *
SQLBIGBINARY unsigned char *
SQLVARBINARY unsigned char *
SQLBIGVARBINARY unsigned char *
SQLBIT char
SQLBITN char
SQLINT1 char
SQLINT2 short int
SQLINT4 int
SQLINT8 _int64
SQLINTN cbIndicator
1: SQLINT1
2: SQLINT2
4: SQLINT4
8: SQLINT8
SQLFLT4 float
SQLFLT8 FLOAT
SQLFLTN cbIndicator
4: SQLFLT4
8: SQLFLT8
SQLDECIMALN SQL_NUMERIC_STRUCT
SQLNUMERICN SQL_NUMERIC_STRUCT
SQLMONEY DBMONEY
SQLMONEY4 DBMONEY4
SQLMONEYN cbIndicator
4: SQLMONEY4
8: SQLMONEY
SQLTIMEN SQL_SS_TIME2_STRUCT
SQLDATEN SQL_DATE_STRUCT
SQLDATETIM4 DBDATETIM4
SQLDATETIME DBDATETIME
SQLDATETIMN cbIndicator
4: SQLDATETIM4
8: SQLDATETIME
SQLDATETIME2N SQL_TIMESTAMP_STRUCT
SQLDATETIMEOFFSETN SQL_SS_TIMESTAMPOFFSET_STRUCT
SQLIMAGE unsigned char *
SQLUDT unsigned char *
SQLUNIQUEID SQLGUID
SQLVARIANT 除以下数据类型之外的任意数据类型
-发短信
- ntext
-图像
- varchar(max)
- varbinary(max)
- nvarchar(max)
- xml
- timestamp
SQLXML 支持的 C 数据类型:
- char*
- wchar_t *
- unsigned char *

idxServerCol 是将数据复制到的数据库表中列的序号位置。 表中的第一列为列 1。 SQLColumns 报告列的序号位置。

返回

SUCCEED 或 FAIL。

注解

使用 bcp_bind 快速、高效地将数据从程序变量复制到 SQL Server 中的表。

调用此函数或任何其他大容量复制函数之前调用 bcp_init 。 调用 bcp_init 设置用于大容量复制的 SQL Server 目标表。 调用bcp_init以用于bcp_bindbcp_sendrow时,bcp_init szDataFile 参数(指示数据文件)设置为 NULL;bcp_initeDirection 参数设置为DB_IN。

对要复制到的 SQL Server 表中的每一列进行单独的 bcp_bind 调用。 进行必要的 bcp_bind 调用后,调用 bcp_sendrow 将一行数据从程序变量发送到 SQL Server。 不支持重新绑定列。

每当希望 SQL Server 提交已收到的行时,请调用 bcp_batch。 例如, 对于插入的每 1000 行或以任何其他间隔调用bcp_batch 一次。

如果没有更多要插入的行,请调用 bcp_done。 如果没有这样做,会导致错误。

使用 bcp_control指定的控制参数设置不会影响 bcp_bind 行传输。

如果列的 pData 设置为 NULL,因为其值将由调用bcp_moretext提供,则 eDataType 设置为 SQLTEXT、SQLNTEXT、SQLXML、SQLUDT、SQLCHARACTER、SQLVARCHAR、SQLVARBINARY、SQLBINARY、SQLNCHAR 或 SQLIMAGE 的任何后续列也必须绑定到 pData 设置为 NULL,并且还必须通过调用bcp_moretext提供其值。

对于新的大型值类型(如 varchar(max)varbinary(max)nvarchar(max),可以使用 eDataType 参数中的 SQLCHARACTER、SQLVARCHAR、SQLVARBINARY、SQLBINARY 和 SQLNCHAR 作为类型指示器。

如果 cbTerm 不是 0,则前缀(cbIndicator)的任何值(1、2、4 或 8)都有效。 在这种情况下,SQL Server Native Client 将搜索终止符,计算终止符(i)的数据长度,并将 cbData 设置为较小的 i 值和前缀值。

如果 cbTerm 为 0 且 cbIndicator (前缀)不是 0,cbIndicator 必须为 8。 8 字节前缀可以采用以下值:

  • 0xFFFFFFFFFFFFFFFF 表示字段为 Null 值。

  • 0xFFFFFFFFFFFFFFFE被视为特殊前缀值,用于有效地将数据分块发送到服务器。 带有此特殊前缀的数据的格式为:

  • <><ZERO_CHUNK以下位置SPECIAL_PREFIX> 0 个或多个数据区块><:

  • SPECIAL_PREFIX 为 0xFFFFFFFFFFFFFFFE

  • DATA_CHUNK是一个包含区块长度的 4 字节前缀,后跟在 4 字节前缀中指定的实际数据。

  • ZERO_CHUNK是一个包含所有零(00000000000)的 4 字节值,指示数据结束。

  • 任何其他有效的 8 字节长度被视为常规数据长度。

使用bcp_bind时调用bcp_columns会导致错误。

bcp_bind 对日期和时间增强功能的支持

有关日期/时间类型的 eDataType 参数中使用的类型的信息,请参阅增强的日期和时间类型的大容量复制更改(OLE DB 和 ODBC)。

有关详细信息,请参阅日期和时间改进(ODBC)。

示例

#include sql.h  
#include sqlext.h  
#include odbcss.h  
// Variables like henv not specified.  
HDBC      hdbc;  
char         szCompanyName[MAXNAME];  
DBINT      idCompany;  
DBINT      nRowsProcessed;  
DBBOOL      bMoreData;  
char*      pTerm = "\t\t";  
  
// Application initiation, get an ODBC environment handle, allocate the  
// hdbc, and so on.  
...
  
// Enable bulk copy prior to connecting on allocated hdbc.  
SQLSetConnectAttr(hdbc, SQL_COPT_SS_BCP, (SQLPOINTER) SQL_BCP_ON,  
   SQL_IS_INTEGER);  
  
// Connect to the data source; return on error.  
if (!SQL_SUCCEEDED(SQLConnect(hdbc, _T("myDSN"), SQL_NTS,  
   _T("myUser"), SQL_NTS, _T("myPwd"), SQL_NTS)))  
   {  
   // Raise error and return.  
   return;  
   }  
  
// Initialize bcp.
if (bcp_init(hdbc, "comdb..accounts_info", NULL, NULL  
   DB_IN) == FAIL)  
   {  
   // Raise error and return.  
   return;  
   }  
  
// Bind program variables to table columns.
if (bcp_bind(hdbc, (LPCBYTE) &idCompany, 0, sizeof(DBINT), NULL, 0,  
   SQLINT4, 1)    == FAIL)  
   {  
   // Raise error and return.  
   return;  
   }  
if (bcp_bind(hdbc, (LPCBYTE) szCompanyName, 0, SQL_VARLEN_DATA,  
   (LPCBYTE) pTerm, strnlen(pTerm, sizeof(pTerm)), SQLCHARACTER, 2) == FAIL)  
   {  
   // Raise error and return.  
   return;  
   }  
  
while (TRUE)  
   {  
   // Retrieve and process program data.
   if ((bMoreData = getdata(&idCompany, szCompanyName)) == TRUE)  
      {  
      // Send the data.
      if (bcp_sendrow(hdbc) == FAIL)  
         {  
         // Raise error and return.  
         return;  
         }  
      }  
   else  
      {  
      // Break out of loop.  
      break;  
      }  
   }  
  
// Terminate the bulk copy operation.  
if ((nRowsProcessed = bcp_done(hdbc)) == -1)  
   {  
   printf_s("Bulk-copy unsuccessful.\n");  
   return;  
   }  
  
printf_s("%ld rows copied.\n", nRowsProcessed);  

另请参阅

大容量复制函数