bcp_init
适用于:SQL Server Azure SQL 数据库 Azure SQL 托管实例 Azure Synapse Analytics Analytics 平台系统(PDW)
初始化大容量复制操作。
语法
RETCODE bcp_init (
HDBC hdbc,
LPCTSTR szTable,
LPCTSTR szDataFile,
LPCTSTR szErrorFile,
INT eDirection);
Unicode 和 ANSI 名称:
- bcp_initA (ANSI)
- bcp_initW (Unicode)
参数
hdbc
已启用大容量复制的 ODBC 连接句柄。
szTable
要向内或向外复制的数据库表的名称。 该名称还可以包含数据库名称或所有者名称。 例如 pubs.gracie.titles、 pubs.。titles、 gracie.titles 和 titles 都是合法的表名。
如果 eDirection DB_OUT,szTable 也可以是数据库视图的名称。
如果在 DB_OUT调用 bcp_exec 之前使用 bcp_control 指定了 eDirection,则必须将 szTable 设置为 NULL bcp_init szTable。
szDataFile
要向内或向外复制的用户文件的名称。 如果使用 bcp_sendrow直接从变量复制数据,请将 szDataFile 设置为 NULL。
szErrorFile
使用进度消息、错误消息,以及出于任何原因无法从用户文件复制到表的任何行的副本填充的错误文件的名称。 如果 NULL 作为 szErrorFile 传递,则不会使用错误文件。
eDirection
复制方向为 DB_IN 或 DB_OUT。 DB_IN 指示从程序变量或用户文件复制到表中。 DB_OUT 指示从数据库表复制到用户文件中。 必须使用 DB_OUT 指定一个用户文件名。
返回
SUCCEED 或 FAIL。
注解
调用任何其他大容量复制函数之前调用 bcp_init 。 bcp_init 对工作站和 SQL Server 之间的大容量数据副本执行必要的初始化。
必须使用启用了 ODBC 连接句柄的 ODBC 连接句柄来提供bcp_init函数,以便与大容量复制函数一起使用。 若要启用句柄,请使用 SQL_COPT_SS_BCP设置为SQL_BCP_ON已分配的连接句柄(但未连接)的 SQLSetConnectAttr 。 尝试对已连接的句柄分配属性将导致错误。
指定数据文件时, bcp_init 检查数据库源表或目标表的结构,而不是数据文件。 bcp_init根据数据库表、视图或 SELECT 结果集中的每一列指定数据文件的数据格式值。 此指定包括每一列的数据类型、数据中是否存在长度或 Null 指示符和终止符字节字符串以及固定长度的数据类型的宽度。 bcp_init设置以下值:
指定的数据类型是数据库表、视图或 SELECT 结果集中的列的数据类型。 数据类型由 sqlncli.h 中指定的 SQL Server 本机数据类型枚举。 数据自身采用它所在的计算机格式表示。 也就是说,整数数据类型列中的数据由基于创建数据文件的计算机的大字节或小字节序列表示。
如果数据库数据类型的长度是固定的,则该数据文件中的数据长度也是固定的。 处理数据(例如, bcp_exec)的大容量复制函数分析数据行,期望数据文件中的数据长度与数据库表、视图或 SELECT 列列表中指定的数据的长度相同。 例如,定义为 char(13) 的数据库列的数据必须由文件中每行数据的 13 个字符表示。 如果数据库列允许 Null 值,则可以使用 Null 指示符作为固定长度的数据的前缀。
定义终止符字节序列时,该终止符字节序列的长度设置为 0。
复制到 SQL Server 时,数据文件必须具有数据库表中每一列的数据。 从 SQL Server 复制时,数据库表、视图或 SELECT 结果集中所有列的数据将复制到数据文件。
复制到 SQL Server 时,数据文件中列的序号位置必须与数据库表中列的序号位置相同。 从 SQL Server 复制时, bcp_exec 根据数据库表中列的序号位置放置数据。
如果数据库数据类型长度可变(例如 varbinary(22)或数据库列可以包含 null 值,则数据文件中的数据以长度/null 指示器为前缀。 指示符的宽度因数据类型和大容量复制的版本而异。
若要更改为数据文件指定的数据格式值,请调用 bcp_columns 和 bcp_colfmt。
可以通过将数据库恢复模式设置为 SIMPLE 或 BULK_LOGGED,针对不包含索引的表优化到 SQL Server 的大容量副本。 有关详细信息,请参阅 批量导入 和 ALTER DATABASE 中最小日志记录的先决条件。
如果未使用数据文件,则必须调用bcp_bind来指定每列数据内存中的格式和位置,然后使用bcp_sendrow将数据行复制到 SQL Server。
示例
此示例显示如何将 ODBC bcp_init 函数用于格式化文件。
编译并运行在 C++ 代码之前,您需要执行以下操作:
创建名为 Test 的 ODBC 数据源。 您可以将此数据源与任何数据库相关联。
对数据库运行以下 Transact-SQL:
CREATE TABLE BCPDate (cola int, colb datetime);
在您将在其中运行应用程序的目录中,添加名为 Bcpfmt.fmt 的文件,并将以下内容添加到此文件中:
8.0 2 1SQLCHAR04"\t"1colaSQL_Latin1_General_Cp437_Bin 2SQLCHAR08"\r\n"2colbSQL_Latin1_General_Cp437_Bin
在您将在其中运行应用程序的目录中,添加名为 Bcpodbc.bcp 的文件,并将以下内容添加到此文件中:
1 2
现在,您可以编译并运行此 C++ 代码了。
// compile with: odbc32.lib sqlncli11.lib
#include <stdio.h>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <odbcss.h>
SQLHENV henv = SQL_NULL_HENV;
HDBC hdbc1 = SQL_NULL_HDBC;
void Cleanup() {
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;
SDWORD cRows;
// 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, set BCP mode, 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);
}
retcode = SQLSetConnectAttr(hdbc1, SQL_COPT_SS_BCP, (void *)SQL_BCP_ON, SQL_IS_INTEGER);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLSetConnectAttr(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);
}
// Initialize the bulk copy.
retcode = bcp_init(hdbc1, "BCPDate", "BCPODBC.bcp", NULL, DB_IN);
if ( (retcode != SUCCEED) ) {
printf("bcp_init(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
// Read the format file.
retcode = bcp_readfmt(hdbc1, "BCPFMT.fmt");
if ( (retcode != SUCCEED) ) {
printf("bcp_readfmt(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
// Execute the bulk copy.
retcode = bcp_exec(hdbc1, &cRows);
if ( (retcode != SUCCEED) ) {
printf("bcp_exec(hdbc1) Failed\n\n");
Cleanup();
return(9);
}
printf("Number of rows bulk copied in = %d.\n", cRows);
// Cleanup
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}