此示例演示如何使用大容量复制函数创建本机模式数据文件,而无需格式化文件。 此示例是为 ODBC 3.0 或更高版本开发的。
重要
请尽可能使用 Windows 身份验证。 如果 Windows 身份验证不可用,则提示用户在运行时输入其凭据。 避免将凭据存储在文件中。 如果必须保留凭据,则应使用 Win32 加密 API 对其进行加密。
在没有格式化文件的情况下批量复制
分配环境句柄和连接句柄。
设置SQL_COPT_SS_BCP和SQL_BCP_ON以启用大容量复制作。
连接到 SQL Server。
调用 bcp_init 以设置以下信息:
要从或向其中批量复制的表或视图的名称。
数据文件的名称,其中包含要复制到数据库中的数据,或者在从数据库复制时接收数据。
要接收任何大容量复制错误消息的数据文件的名称(如果不希望消息文件,请指定 NULL)。
复制的方向:从文件DB_IN到视图或表,或者从表或视图中DB_OUT文件。
调用 bcp_exec 以执行大容量复制作。
使用这些步骤设置DB_OUT时,会以本机格式创建该文件。 然后,可以按照相同的步骤将文件批量复制到服务器,但设置DB_OUT而不是DB_IN。 仅当源表和目标表具有相同的结构时,这才有效。
示例:
IA64 不支持此示例。
需要一个名为 AdventureWorks 的 ODBC 数据源,其默认数据库是 AdventureWorks 示例数据库。 (可以从 Microsoft SQL Server 示例和社区项目 主页下载 AdventureWorks 示例数据库。此数据源必须基于作系统提供的 ODBC 驱动程序(驱动程序名称为“SQL Server”)。 如果要在 64 位作系统上生成并运行此示例作为 32 位应用程序,则必须在 %windir%\SysWOW64\odbcad32.exe中使用 ODBC 管理员创建 ODBC 数据源。
此示例连接到计算机的默认 SQL Server 实例。 若要连接到命名实例,请更改 ODBC 数据源的定义,以使用以下格式指定实例:服务器\namedinstance。 默认情况下,SQL Server Express 安装到命名实例。
使用 odbc32.lib 和 odbcbcp.lib 进行编译。
// compile with: odbc32.lib odbcbcp.lib
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <odbcss.h>
#define MAXBUFLEN 256
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;
// Bulk copy variables.
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 bulk copy mode, and then 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 the SQL Server DSN using Windows NT authentication.
retcode = SQLConnect(hdbc1, (UCHAR*)"AdventureWorks", 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, "Purchasing.Vendor", "BCPODBC.bcp", "BCPERROR.out", DB_OUT);
// Test is for the bulk copy return of SUCCEED, not the ODBC return of SQL_SUCCESS.
if ( (retcode != SUCCEED) ) {
printf("bcp_init(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 out = %d.\n", cRows);
// Cleanup
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}