プログラム変数からの一括コピー

プログラム変数から直接一括コピーできます。行のデータを保持する変数を割り当て、bcp_init を呼び出して一括コピーを開始した後、列ごとに bcp_bind を呼び出し、その列に関連付けるプログラム変数の場所と形式を指定します。各変数にデータを格納したら、bcp_sendrow を呼び出してサーバーにデータ行を 1 行送信します。すべての行がサーバーに送信されるまで、変数へのデータの格納と bcp_sendrow の呼び出しを繰り返してから、bcp_done を呼び出して操作が完了したことを示します。

bcp_bindpData パラメータは、列にバインドする変数のアドレスを保持します。各列のデータは、次の 2 つの方法のいずれかを使用して格納できます。

  • データを保持する変数を 1 つ割り当てる

  • データ変数の直前にインジケータ変数を割り当てる

インジケータ変数は、可変長列のデータの長さを示します。列で NULL 値を許容している場合は NULL 値も示します。データ変数のみを使用する場合は、この変数のアドレスが bcp_bindpData パラメータに格納されます。インジケータ変数を使用する場合は、インジケータ変数のアドレスが bcp_bindpData パラメータに格納されます。一括コピー関数は、bcp_bindcbIndicator パラメータと pData パラメータを加算することで、データ変数の場所を計算します。

bcp_bind では、次の 3 つの可変長データの処理方法をサポートします。

  • cbData とデータ変数だけを併用します。cbData には、データ長を指定します。一括コピーするデータの長さが変化するたびに、bcp_collen を呼び出して cbData をリセットします。他の 2 つの方法のいずれかを使用する場合は、cbData に SQL_VARLEN_DATA を指定します。また、列に格納するすべてのデータ値が NULL の場合は、cbData に SQL_NULL_DATA を指定します。

  • インジケータ変数を使用します。新しい各データ値をデータ変数に移動するときに、その値の長さをインジケータ変数に格納します。他の 2 つの方法のいずれかを使用する場合は、cbIndicator に 0 を指定します。

  • ターミネータ ポインタを使用します。データを終了するビット パターンのアドレスを bcp_bindpTerm パラメータに読み込みます。他の 2 つの方法のいずれかを使用する場合は、pTerm に NULL を指定します。

これら 3 つの方法はすべて、1 つの bcp_bind 呼び出しに対して使用できます。この場合、コピーされるデータが最も少なくなる指定方法が使用されます。

bcp_bindtype パラメータは、ODBC のデータ型識別子ではなく、DB-Library のデータ型識別子を使用します。ODBC bcp_bind 関数で使用できる DB-Library のデータ型識別子は、sqlncli.h 内に定義されています。

一括コピー関数では、すべての ODBC C データ型をサポートしているわけではありません。たとえば、一括コピー関数では、ODBC SQL_C_TYPE_TIMESTAMP 構造体をサポートしないので、ODBC SQL_TYPE_TIMESTAMP 型のデータを SQL_C_CHAR 型の変数に変換するには、SQLBindColSQLGetData を使用します。その後、type パラメータに SQLCHARACTER を指定して bcp_bind を呼び出し、変数を SQL Server の datetime 型の列にバインドする場合、一括コピー関数では、文字変数内のタイムスタンプ エスケープ句を適切な日付時刻形式に変換します。

次の表に、ODBC SQL データ型から SQL Server データ型へのマッピングを行う際に使用が推奨されるデータ型を示します。

ODBC SQL データ型

ODBC C データ型

bcp_bind の type パラメータ

SQL Server データ型

SQL_CHAR

SQL_C_CHAR

SQLCHARACTER

character

char

SQL_VARCHAR

SQL_C_CHAR

SQLCHARACTER

varchar

character varying

char varying

sysname

SQL_LONGVARCHAR

SQL_C_CHAR

SQLCHARACTER

text

SQL_WCHAR

SQL_C_WCHAR

SQLNCHAR

nchar

SQL_WVARCHAR

SQL_C_WCHAR

SQLNVARCHAR

nvarchar

SQL_WLONGVARCHAR

SQL_C_WCHAR

SQLNTEXT

ntext

SQL_DECIMAL

SQL_C_CHAR

SQLCHARACTER

decimal

dec

money

smallmoney

SQL_NUMERIC

SQL_C_NUMERIC

SQLNUMERICN

numeric

SQL_BIT

SQL_C_BIT

SQLBIT

bit

SQL_TINYINT (符号付き)

SQL_C_SSHORT

SQLINT2

smallint

SQL_TINYINT (符号なし)

SQL_C_UTINYINT

SQLINT1

tinyint

SQL_SMALL_INT (符号付き)

SQL_C_SSHORT

SQLINT2

smallint

SQL_SMALL_INT (符号なし)

SQL_C_SLONG

SQLINT4

int

integer

SQL_INTEGER (符号付き)

SQL_C_SLONG

SQLINT4

int

integer

SQL_INTEGER (符号なし)

SQL_C_CHAR

SQLCHARACTER

decimal

dec

SQL_BIGINT (符号付きと符号なし)

SQL_C_CHAR

SQLCHARACTER

bigint

SQL_REAL

SQL_C_FLOAT

SQLFLT4

real

SQL_FLOAT

SQL_C_DOUBLE

SQLFLT8

float

SQL_DOUBLE

SQL_C_DOUBLE

SQLFLT8

float

SQL_BINARY

SQL_C_BINARY

SQLBINARY

binary

timestamp

SQL_VARBINARY

SQL_C_BINARY

SQLBINARY

varbinary

binary varying

SQL_LONGVARBINARY

SQL_C_BINARY

SQLBINARY

image

SQL_TYPE_DATE

SQL_C_CHAR

SQLCHARACTER

datetime

smalldatetime

SQL_TYPE_TIME

SQL_C_CHAR

SQLCHARACTER

datetime

smalldatetime

SQL_TYPE_TIMESTAMP

SQL_C_CHAR

SQLCHARACTER

datetime

smalldatetime

SQL_GUID

SQL_C_GUID

SQLUNIQUEID

uniqueidentifier

SQL_INTERVAL_

SQL_C_CHAR

SQLCHARACTER

char

SQL Server には、符号付きの tinyint 型、符号なしの smallint 型、または符号なしの int 型が用意されていません。これらのデータ型を変換するときにデータ値が失われないようにするには、2 番目に大きい整数データ型を使用して SQL Server テーブルを作成します。ユーザーが元のデータ型で許容されている範囲外の値を後から追加しないようにするには、次のようにルールを SQL Server 列に適用し、ソースのデータ型でサポートされる範囲内に許容値を限定します。

CREATE TABLE Sample_Ints(STinyIntCol   SMALLINT,
USmallIntCol INT)
GO
CREATE RULE STinyInt_Rule
AS 
@range >= -128 AND @range <= 127
GO
CREATE RULE USmallInt_Rule
AS 
@range >= 0 AND @range <= 65535
GO
sp_bindrule STinyInt_Rule, 'Sample_Ints.STinyIntCol'
GO
sp_bindrule USmallInt_Rule, 'Sample_Ints.USmallIntCol'
GO

SQL Server では、interval データ型を直接サポートしません。ただしアプリケーションでは、interval 型のエスケープ シーケンスを文字列として SQL Server 文字型列に格納できます。アプリケーションでは、後で使用するためにこれらのエスケープ シーケンスを読み取ることができますが、Transact-SQL ステートメント内では使用できません。

一括コピー関数を使用すると、ODBC データ ソースから読み取ったデータを SQL Server にすばやく読み込むことができます。SQLBindCol を使用して結果セットの列をプログラム変数にバインドしてから bcp_bind を使用すると、それらのプログラム変数が一括コピー操作にバインドされます。また、SQLFetchScroll または SQLFetch を呼び出すと、データ行が ODBC データ ソースからプログラム変数にフェッチされ、bcp_sendrow を呼び出すと、そのデータがプログラム変数から SQL Server に一括コピーされます。

bcp_bindpData パラメータに対して指定したデータ変数のアドレスを変更する必要があるときは、アプリケーションでは、いつでも bcp_colptr 関数を使用できます。また、bcp_bindcbData パラメータに対して指定したデータの長さを変更する必要があるときは、いつでも、bcp_collen 関数を使用できます。

"bcp_readrow" のような関数は用意されていないため、一括コピーを使用してデータを SQL Server からプログラム変数に読み取ることはできません。実行できるのは、アプリケーションからサーバーへのデータの送信だけです。