bcp_bind
適用於: SQL Server Azure SQL 資料庫 Azure SQL 受控執行個體 Azure Synapse Analytics Analytics Platform System (PDW)
將數據從程式變數系結至數據表數據行,以便大量複製到 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 表示會使用 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 數據類型標記所列舉,而不是 ODBC C 數據類型列舉值。 例如,您可以使用 SQL Server 特定類型SQLINT2來指定雙位元組整數 ODBC 類型SQL_C_SHORT。
SQL Server 2005 (9.x) 引進了 eDataType 參數中 SQLXML 和 SQLUDT 數據類型令牌的支援。
下表列出有效的列舉數據類型和對應的 ODBC C 數據類型。
eDataType | C 類型 |
---|---|
SQLTEXT | char * |
SQLNTEXT | wchar_t * |
SQLCHARACTER | char * |
SQLBIGCHAR | char * |
SQLVARCHAR | char * |
SQLBIGVARCHAR | char * |
SQLNCHAR | wchar_t * |
SQLNVARCHAR | wchar_t * |
SQLBINARY | unsigned char * |
SQLBIGBINARY | unsigned char * |
SQLVARBINARY | unsigned char * |
SQLBIGVARBINARY | unsigned char * |
SQLBIT | char |
SQLBITN | char |
SQLINT1 | char |
SQLINT2 | short int |
SQLINT4 | int |
SQLINT8 | _int64 |
SQLINTN | cbIndicator 1:SQLINT1 2: SQLINT2 4: SQLINT4 8:SQLINT8 |
SQLFLT4 | float |
SQLFLT8 | float |
SQLFLTN | cbIndicator 4: SQLFLT4 8:SQLFLT8 |
SQLDECIMALN | SQL_NUMERIC_STRUCT |
SQLNUMERICN | SQL_NUMERIC_STRUCT |
SQLMONEY | DBMONEY |
SQLMONEY4 | DBMONEY4 |
SQLMONEYN | cbIndicator 4: SQLMONEY4 8:SQLMONEY |
SQLTIMEN | SQL_SS_TIME2_STRUCT |
SQLDATEN | SQL_DATE_STRUCT |
SQLDATETIM4 | DBDATETIM4 |
SQLDATETIME | DBDATETIME |
SQLDATETIMN | cbIndicator 4:SQLDATETIM4 8:SQLDATETIME |
SQLDATETIME2N | SQL_TIMESTAMP_STRUCT |
SQLDATETIMEOFFSETN | SQL_SS_TIMESTAMPOFFSET_STRUCT |
SQLIMAGE | unsigned char * |
SQLUDT | unsigned char * |
SQLUNIQUEID | SQLGUID |
SQLVARIANT | 除了下列任何資料類型: - 文字 - ntext - 影像 - varchar(max) - varbinary(max) - nvarchar(max) - xml -時間戳 |
SQLXML | 支援的 C 資料型態: -煳* - wchar_t * - 不帶正負號的字元 * |
idxServerCol 是數據複製到資料庫數據表中數據行的序數位置。 數據表中的第一個數據行是數據行 1。 SQLColumns 會報告數據行的序數位置。
傳回
SUCCEED 或FAIL。
備註
使用 bcp_bind ,以快速且有效率的方式將數據從程式變數複製到 SQL Server 中的數據表。
呼叫此函式或任何其他大量複製函式之前,請先呼叫 bcp_init 。 呼叫 bcp_init 設定大量複製的 SQL Server 目標數據表。 呼叫 bcp_init 以搭配 bcp_bind 和 bcp_sendrow 使用時, bcp_init szDataFile 參數會設定為 NULL; bcp_initeDirection 參數會設定為 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 設定為 NULL,因為其值會透過呼叫 bcp_moretext 提供,則任何將 eDataType 設為 SQLTEXT、SQLNTEXT、SQLXML、SQLUDT、SQLCHARACTER、SQLVARCHAR、SQLVARBINARY、SQLBINARY、SQLNCHAR 或 SQLIMAGE 的後續數據行也必須系結為 NULL,而且其值也必須由呼叫 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 個以上的數據區塊><ZERO_CHUNK>其中:
SPECIAL_PREFIX為0xFFFFFFFFFFFFFFFE
DATA_CHUNK是包含區塊長度的 4 位元組前置詞,後面接著在 4 位元組前置詞中指定其長度的實際數據。
ZERO_CHUNK是一個 4 位元組值,其中包含表示數據結束的所有零(0000000000)。
任何其他有效的8位元組長度都會被視為一般數據長度。
使用bcp_bind時呼叫bcp_columns會導致錯誤。
bcp_bind增強日期和時間功能的支援
如需與日期/時間類型 eDataType 參數搭配使用的類型相關信息,請參閱增強型日期和時間類型的大量複製變更(OLE DB 和 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);