批量复制 SELECT 结果集 (ODBC)

此示例演示如何使用大容量复制函数批量复制 SELECT 语句的结果集。 此示例是为 ODBC 3.0 或更高版本开发的。

重要

请尽可能使用 Windows 身份验证。 如果 Windows 身份验证不可用,则提示用户在运行时输入其凭据。 避免将凭据存储在文件中。 如果必须保留凭据,则应使用 Win32 加密 API 对其进行加密

大容量复制 SELECT 语句的结果集

  1. 分配环境句柄和连接句柄。

  2. 设置SQL_COPT_SS_BCP和SQL_BCP_ON以启用大容量复制作。

  3. 连接到 SQL Server。

  4. 调用 bcp_init 以设置以下信息:

    • szTable 参数指定 NULL。

    • 接收结果集数据的数据文件的名称。

    • 要接收任何大容量复制错误消息的数据文件的名称(如果不希望消息文件,请指定 NULL)。

    • 副本的方向:DB_OUT。

  5. 调用 bcp_control,将 eOption 设置为 BCPHINTS,并将指针置于 iValue 中,指向包含 SELECT 语句的 SQLTCHAR 数组。

  6. 调用 bcp_exec 以执行大容量复制作。

按以上步骤操作时文件是以本机格式创建的。 可以使用 bcp_colfmt将数据值转换为其他数据类型。 有关详细信息,请参阅创建大容量复制格式化文件(ODBC)。

示例:

需要一个名为 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;  
   SQLTCHAR szBCPQuery[] = "SELECT BirthDate FROM HumanResources.Employee";  
  
   // 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 use Integrated Security, create 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, NULL, "BCPODBC.bcp", "BCPERROR.out", DB_OUT);  
   // The 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);  
   }  
  
   // Specify the query to use.  
   retcode = bcp_control(hdbc1, BCPHINTS, (void *)szBCPQuery);  
   if ( (retcode != SUCCEED) ) {  
      printf("bcp_control(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);  
}  

另请参阅

使用 SQL Server ODBC 驱动程序作指南主题批量复制 (ODBC)