从程序变量执行大容量复制
可以直接从程序变量执行大容量复制。 在分配用于保存行数据的变量并调用 bcp_init 启动大容量复制之后,为每一列调用 bcp_bind 来指定要与该列关联的程序变量的位置和格式。 用数据填充每个变量,然后调用 bcp_sendrow 向服务器发送一行数据。 重复填充变量和调用 bcp_sendrow 的过程,直到向服务器发送了所有行,然后调用 bcp_done 指定操作已完成。
bcp_bind pData 参数包含绑定到列的变量的地址。 每列的数据都可以通过以下两种方式之一存储:
分配一个变量以保存数据。
分配指示器变量,后面紧随数据变量。
指示器变量指示可变长度列的数据长度,如果列允许 NULL 值,还指示 NULL 值。 如果仅使用数据变量,则此变量的地址存储在 bcp_bind pData 参数中。 如果使用指示器变量,指示器变量的地址存储在 bcp_bind pData 参数中。 大容量复制函数通过将 bcp_bind cbIndicator 和 pData 参数相加来计算数据变量的位置。
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 结构,所以应使用 SQLBindCol 或 SQLGetData 将 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 将这些程序变量绑定到大容量复制操作。 调用 SQLFetchScroll 或 SQLFetch,然后将数据行从 ODBC 数据源提取到程序变量中,再调用 bcp_sendrow 将这些数据从程序变量大容量复制到 SQL Server。
应用程序可以根据需要随时使用 bcp_colptr 函数更改最初在 bcp_bind pData 参数中指定的数据变量的地址。 应用程序可以根据需要随时使用 bcp_collen 函数来更改最初在 bcp_bind cbData 参数中指定的数据长度。
无法使用大容量复制功能将数据从 SQL Server 读取到程序变量中;没有与 "bcp_readrow" 函数类似的功能。 只能将数据从应用程序发送到服务器。