bcp_bind
適用対象: SQL Server Azure SQL データベース Azure SQL Managed Instance 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 で終わる空の文字列は 1 バイト (ターミネータ バイト自体) を構成するため、 cbTerm を 1 に設定します。 たとえば、 szName の文字列が null で終わると、ターミネータを使用して長さを示す必要があることを示します。
bcp_bind(hdbc, szName, 0,
SQL_VARLEN_DATA, "", 1,
SQLCHARACTER, 2)
この例の非終端形式は、 szName 変数からバインドされたテーブルの 2 番目の列に 15 文字がコピーされることを示している可能性があります。
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 パラメーターは、ODBC C データ型列挙子ではなく、sqlncli.h の SQL Server データ型トークンによって列挙されます。 たとえば、SQL Server 固有の型SQLINT2を使用して、2 バイト整数の 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 - timestamp |
SQLXML | サポートされる C のデータ型 - char* - wchar_t * - unsigned char * |
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_initeDirection パラメーターは DB_IN に設定されます。
コピー先の SQL Server テーブル内のすべての列に対して個別の bcp_bind 呼び出しを行います。 必要な bcp_bind 呼び出しが行われた後、 bcp_sendrow を呼び出して、プログラム変数から SQL Server にデータの行を送信します。 列の再バインドはサポートされていません。
SQL Server で既に受信した行をコミットする場合は常に、 bcp_batchを呼び出します。 たとえば、挿入された 1,000 行ごとに、または他の間隔で 1 回 bcp_batch を呼び出します。
挿入する行がこれ以上ない場合は、 bcp_doneを呼び出します。 この操作を行わないと、エラーが発生します。
bcp_controlで指定された制御パラメーター設定は、bcp_bind行転送には影響しません。
列 pData の値は bcp_moretextの呼び出しによって提供されるため、NULL に設定されます。 eDataType SQLTEXT、SQLNTEXT、SQLXML、SQLUDT、SQLCHARACTER、SQLVARCHAR、SQLVARBINARY、SQLBINARY、SQLNCHAR、または SQLIMAGE に設定されている後続の列も、 pData NULL に設定してバインドする必要があり、その値は bcp_moretextの呼び出しによっても提供される必要があります。
varchar(max)、varbinary(max)、nvarchar(max)など、新しい大きな値の型の場合は、eDataType パラメーターの型インジケーターとして SQLCHARACTER、SQLVARCHAR、SQLVARBINARY、SQLBINARY、SQLNCHAR を使用できます。
cbTerm が 0 でない場合、プレフィックス (cbIndicator) に対して任意の値 (1、2、4、または 8) が有効です。 このような場合、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は、データの終わりを示すゼロ (00000000) をすべて含む 4 バイトの値です。
その他の有効な 8 バイトの長さは、通常のデータ長として扱われます。
bcp_bindを使用するときにbcp_columnsを呼び出すと、エラーが発生します。
bcp_bind による機能強化された日付と時刻のサポート
日付/時刻型の eDataType パラメーターで使用される型の詳細については、「 拡張日付と時刻型の変更のコピー (OLE DB および ODBC)を参照してください。
詳細については、「 Date and Time Improvements (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);