从程序变量执行大容量复制

可以直接从程序变量执行大容量复制。 在分配用于保存行数据的变量并调用 bcp_init 启动大容量复制之后,为每一列调用 bcp_bind 来指定要与该列关联的程序变量的位置和格式。 用数据填充每个变量,然后调用 bcp_sendrow 向服务器发送一行数据。 重复填充变量和调用 bcp_sendrow 的过程,直到向服务器发送了所有行,然后调用 bcp_done 指定操作已完成。

bcp_bind pData 参数包含绑定到列的变量的地址。 每列的数据都可以通过以下两种方式之一存储:

  • 分配一个变量以保存数据。

  • 分配指示器变量,后面紧随数据变量。

指示器变量指示可变长度列的数据长度,如果列允许 NULL 值,还指示 NULL 值。 如果仅使用数据变量,则此变量的地址存储在 bcp_bind pData 参数中。 如果使用指示器变量,指示器变量的地址存储在 bcp_bind pData 参数中。 大容量复制函数通过将 bcp_bind cbIndicatorpData 参数相加来计算数据变量的位置。

bcp_bind 支持使用三种方法来处理可变长度数据:

  • 仅将 cbData 用于数据变量。 将数据的长度存放在 cbData 中。 在每次要执行大容量复制的数据的长度更改时,调用 bcp_collen以重置 cbData。 如果使用另外两种方法之一,则为 cbData 指定 SQL_VARLEN_DATA。 如果为某列提供的所有数据值均为 NULL,则为 cbData 指定 SQL_NULL_DATA。

  • 使用指示器变量。 随着每个新数据值移入数据变量,将该值的长度存储在指示器变量中。 如果使用另外两种方法之一,则为 cbIndicator 指定 0。

  • 使用终止符指针。 加载 bcp_bind pTerm 参数(其中带有用于终止数据的位模式的地址)。 如果使用另外两种方法之一,则为 pTerm 指定 NULL。

可以对同一 bcp_bind 调用使用上述所有三种方法,在这种情况下,将使用导致复制的数据量最小的指定方式。

bcp_bind type 参数使用 DB-Library 数据类型标识符,而不是 ODBC 数据类型标识符。 DB-Library 数据类型标识符在 sqlncli.h 中定义,与 ODBC bcp_bind 函数一同使用。

大容量复制函数并不支持所有 ODBC C 数据类型。 例如,大容量复制函数不支持 ODBC SQL_C_TYPE_TIMESTAMP 结构,所以应使用 SQLBindColSQLGetData 将 ODBC SQL_TYPE_TIMESTAMP 数据转换为 SQL_C_CHAR 变量。 如果随后使用 bcp_bind(带有 type 参数 SQLCHARACTER)将该变量绑定到 SQL Server datetime 列,大容量复制函数会将字符变量中的时间戳转义子句转换为正确的 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 等数据类型。 若要在迁移这些数据类型时防止丢失数据值,应使用第二大整数数据类型创建 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 将这些程序变量绑定到大容量复制操作。 调用 SQLFetchScrollSQLFetch,然后将数据行从 ODBC 数据源提取到程序变量中,再调用 bcp_sendrow 将这些数据从程序变量大容量复制到 SQL Server。

应用程序可以根据需要随时使用 bcp_colptr 函数更改最初在 bcp_bind pData 参数中指定的数据变量的地址。 应用程序可以根据需要随时使用 bcp_collen 函数来更改最初在 bcp_bind cbData 参数中指定的数据长度。

无法使用大容量复制功能将数据从 SQL Server 读取到程序变量中;没有与 "bcp_readrow" 函数类似的功能。 只能将数据从应用程序发送到服务器。

请参阅

概念

执行大容量复制操作 (ODBC)