bcp_bind
將程式變數中的資料繫結至資料表資料行,以便在 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 是表示 Long 資料值將以使用 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 資料類型 Token,而非透過 ODBC C 資料類型列舉值列舉。 例如,您可以使用 SQL Server 專屬類型 SQLINT2 來指定兩個位元組的整數 ODBC 類型 SQL_C_SHORT。
SQL Server 2005 已在 eDataType 參數中導入 SQLXML 和 SQLUDT 資料類型 Token 的支援。
idxServerCol
這是資料庫資料表中要將資料複製到其中之資料行的序數位置。 資料表中的第一個資料行是資料行 1。 資料行的序數位置是由 SQLColumns 所報告。
傳回值
SUCCEED 或 FAIL。
備註
使用 bcp_bind,以快速、有效的方式將資料從程式變數複製到 SQL Server 的資料表中。
呼叫 bcp_init,然後再呼叫此大量複製函數或其他任何大量複製函數。 呼叫 bcp_init 可設定用於大量複製的 SQL Server 目標資料表。 呼叫搭配 bcp_bind 和 bcp_sendrow 使用的 bcp_init 時,包括資料檔案的 bcp_init szDataFile 參數會設定為 NULL,而 bcp_init eDirection 參數則會設定為 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 因為其值將透過 bcp_moretext 的呼叫提供而設定為 NULL,eDataType 設定為 SQLTEXT、SQLNTEXT、SQLXML、SQLUDT、SQLCHARACTER、SQLVARCHAR、SQLVARBINARY、SQLBINARY、SQLNCHAR 或 SQLIMAGE 的其他後續資料行也必須與設定為 NULL 的 pData 繫結,而且其值也必須透過 bcp_moretext 的呼叫提供。
對於新的大數值類型,例如,varchar(max)、varbinary(max) 或 nvarchar(max),您可以使用 SQLCHARACTER、SQLVARCHAR、SQLVARBINARY、SQLBINARY 和 SQLNCHAR 做為 eDataType 參數中的類型指標。
如果 cbTerm 不是 0,任何值 (1、2、4 或 8) 都適用於前置詞 (cbIndicator)。 在此情況下,SQL Server Native Client 將會搜尋結束字元、計算結束字元 (i) 的資料長度,以及將 cbData 設定為較小的 i 值與前置詞的值。
如果 cbTerm 是 0,而且 cbIndicator (前置詞) 不是 0,則 cbIndicator 必須是 8。 8 位元組前置詞可以採用下列值:
0xFFFFFFFFFFFFFFFF 表示欄位的 Null 值
0xFFFFFFFFFFFFFFFE 會視為特殊的前置詞值,用於將區塊中的資料有效傳送到伺服器。 包含此特殊前置詞之資料的格式為:
<SPECIAL_PREFIX> <0 或更多 DATA CHUNKS> <ZERO_CHUNK>,其中:
SPECIAL_PREFIX 是 0xFFFFFFFFFFFFFFFE
DATA_CHUNK 是包含區塊長度的 4 位元組前置詞,後面接著以 4 位元組前置詞指定其長度的實際資料。
ZERO_CHUNK 是包含全部零 (00000000) 的 4 位元組值,表示資料的結尾。
其他任何有效的 8 位元組長度會視為一般資料長度。
使用 bcp_bind 時呼叫 bcp_columns 會導致錯誤。
bcp_bind 支援增強的日期和時間功能
如需有關搭配日期/時間類型之 eDataType 參數使用的類型詳細資訊,請參閱<增強型日期/時間類型的大量複製變更 (OLE DB 和 ODBC)>。
如需詳細資訊,請參閱<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);