bcp_init
初始化大量複製作業。
語法
RETCODE bcp_init (
HDBC hdbc,
LPCTSTR szTable,
LPCTSTR szDataFile,
LPCTSTR szErrorFile,
INT eDirection);
引數
hdbc
這是已啟用大量複製的 ODBC 連接控制代碼。szTable
這是要來回複製之資料庫資料表的名稱。 此名稱也可以包含資料庫名稱或擁有者名稱。 例如,pubs.gracie.titles、pubs..titles、gracie.titles 和 titles 全部都是合法的資料表名稱。如果 eDirection 為 DB_OUT,szTable 也可以做為資料庫檢視的名稱。
如果 eDirection 為 DB_OUT,而且 SELECT 陳述式是在呼叫 bcp_exec 前使用 bcp_control 指定的,bcp_init szTable 必須設定為 NULL。
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 之間的資料大量複製,執行必要的初始化。
bcp_init 函數必須與已啟用的 ODBC 連接控制代碼一起提供,才能搭配大量複製函數使用。 若要啟用控制代碼,當 SQL_COPT_SS_BCP 設定為 SQL_BCP_ON 時,請在已配置但未連接的連接控制代碼上使用 SQLSetConnectAttr。 嘗試在已連接的控制代碼上指派屬性會導致錯誤。
指定資料檔案時,bcp_init 會檢查資料庫來源或目標資料表 (而非資料檔案) 的結構。 bcp_init 會根據資料庫資料表、檢視或 SELECT 結果集中的每個資料行,指定資料檔案的資料格式值。 這個指定包括每個資料行的資料類型、資料中是否有長度或 null 指標和結束字元位元組字串,以及固定長度資料類型的寬度。 bcp_init 會設定這些值,如下所示:
指定的資料類型為資料行在資料庫資料表、檢視或 SELECT 結果集中的資料類型。 資料類型會由 sqlncli.h 中所指定的 SQL Server 原生資料類型列舉。 資料本身會以其電腦格式表示。 也就是說,來自 integer 資料類型之資料行的資料會根據建立資料檔案之電腦,以四個位元組由大到小或由小到大的順序表示。
如果資料庫資料類型的長度是固定的,資料檔案資料的長度也是固定的。 處理資料的大量複製函數 (例如,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。
SQL Server 的大量複製可以針對不包含索引的資料表進行最佳化,方法是,將資料庫復原模式設定為 SIMPLE 或 BULK_LOGGED。 如需詳細資訊,請參閱<大量匯入採用最低限度記錄的必要條件>和<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);
}