执行大容量复制操作

SQL Server 大容量复制功能支持将大量数据传输到 SQL Server 表或视图中,或从其中传出。也可以通过指定 SELECT 语句将数据传出。可以在 SQL Server 和操作系统的数据文件(比如 ASCII 文件)之间移动数据。数据文件可以有不同格式;定义格式是为了对格式文件中的数据进行大容量复制。也可以选择将数据加载到程序变量中,然后使用大容量复制函数和方法将数据传输到 SQL Server。

CodePlex 具有说明此功能的示例应用程序;有关详细信息,请参阅 SQL Server 数据库引擎示例。应用程序通常按以下方式之一使用大容量复制:

  • 从表、视图或 Transact-SQL 语句的结果集,将数据大容量复制到以与该表或视图相同的格式存储数据的数据文件中。

    这称为本机模式数据文件。

  • 从表、视图或 Transact-SQL 语句的结果集,将数据大容量复制到以不同于该表或视图的格式存储数据的数据文件中。

    这种情况下,将创建一个单独的格式文件,用于定义每个列存储在数据文件中时的特征(数据类型、位置、长度、终止符等等)。如果所有列均转换为字符格式,则所产生的文件称为字符模式的数据文件。

  • 从数据文件大容量复制到表或视图中。

    如果需要,则使用格式文件确定数据文件的布局。

  • 将数据加载到程序变量中,然后使用大容量复制函数将数据导入表或视图中,以便一次一行执行大容量复制。

大容量复制函数使用的数据文件不必由另一个大容量复制程序创建。任何其他系统都可以按照大容量复制的定义生成数据文件和格式文件;然后,SQL Server 大容量复制程序可以使用这些文件将数据导入 SQL Server 中。例如,可以将数据从电子表格导出到以制表符分隔的文件中,然后生成描述该制表符分隔文件的格式文件,之后使用大容量复制程序将此数据快速导入 SQL Server 中。还可以将大容量复制所生成的数据文件导入其他应用程序中。例如,可以使用大容量复制函数将数据从表或视图导出到以制表符分隔的文件中,然后可以将该文件加载到电子表格中。

注意注意

从 SQL Server 2005 开始,使用 bcp 实用工具时,如果发生数字数据截断,服务器会报告错误。而 SQL Server 2000 和更早版本仅返回警告。对于忽略警告的现有应用程序,这可能导致问题。只要确保输入数据有不会截断的正确值,或继续使用 SQL Server 2000 版的 bcp,即可避免这些问题。

编写应用程序以使用大容量复制函数的程序员应当遵从常规规则,以获得良好的大容量复制性能。有关 SQL Server 对大容量复制操作的支持的详细信息,请参阅 关于大容量导入和大容量导出操作

限制和局限

CLR 用户定义类型 (UDT) 必须绑定为二进制数据。即使格式文件指定将 SQLCHAR 作为目标 UDT 列的数据类型,BCP 实用工具仍会将数据视为二进制。

不要对大容量复制操作使用 SET FMTONLY OFF。SET FMTONLY OFF 可能导致大容量复制操作失败,或导致意外的结果。

SQL Server Native Client OLE DB 访问接口

SQL Server Native Client OLE DB 访问接口实现两个方法来对 SQL Server 数据库执行大容量复制操作。第一个方法涉及使用 IRowsetFastLoad 接口进行基于内存的大容量复制操作;第二个方法涉及使用 IBCPSession 接口进行基于文件的大容量复制操作。

使用基于内存的大容量复制操作

SQL Server Native Client OLE DB 访问接口实现了 IRowsetFastLoad 接口,以公开对 SQL Server 基于内存的大容量复制操作的支持。IRowsetFastLoad 接口实现了 IRowsetFastLoad::CommitIRowsetFastLoad::InsertRow 方法。

为 IRowsetFastLoad 启用会话

通过将特定于 SQL Server Native Client OLE DB 访问接口的数据源属性 SSPROP_ENABLEFASTLOAD 设置为 VARIANT_TRUE,使用者将其对大容量复制的需要通知 SQL Server Native Client OLE DB 访问接口。通过对数据源设置该属性,使用者创建 SQL Server Native Client OLE DB 访问接口会话。新会话允许使用者访问 IRowsetFastLoad 接口。

注意注意

如果 IDataInitialize 接口用于初始化数据源,则需要在 IOpenRowset::OpenRowset 方法的 rgPropertySets 参数中设置 SSPROP_IRowsetFastLoad 属性;否则,对 OpenRowset 方法的调用将返回 E_NOINTERFACE。

启用大容量复制会话将会约束 SQL Server Native Client OLE DB 访问接口在会话中对接口的支持。启用大容量复制的会话仅公开以下接口:

  • IDBSchemaRowset

  • IGetDataSource

  • IOpenRowset

  • ISupportErrorInfo

  • ITransactionJoin

若要禁止创建启用大容量复制的行集,并使 SQL Server Native Client OLE DB 访问接口会话恢复到标准处理,请将 SSPROP_ENABLEFASTLOAD 重置为 VARIANT_FALSE。

IRowsetFastLoad 行集

SQL Server Native Client OLE DB 访问接口大容量复制行集是只写的,但它们公开的接口允许使用者确定 SQL Server 表的结构。启用大容量复制的 SQL Server Native Client OLE DB 访问接口行集公开了以下接口:

  • IAccessor

  • IColumnsInfo

  • IColumnsRowset

  • IConvertType

  • IRowsetFastLoad

  • IRowsetInfo

  • ISupportErrorInfo

特定于访问接口的属性 SSPROP_FASTLOADOPTIONS、SSPROP_FASTLOADKEEPNULLS 和 SSPROP_FASTLOADKEEPIDENTITY 控制 SQL Server Native Client OLE DB 访问接口大容量复制行集的行为。可以在 rgPropertySetsIOpenRowset 参数成员的 rgProperties 成员中指定这些属性。

属性 ID

说明

SSPROP_FASTLOADKEEPIDENTITY

列:无

R/W:读/写

类型:VT_BOOL

默认值:VARIANT_FALSE

说明:维护使用者提供的标识值。

VARIANT_FALSE:SQL Server 表中的标识列的值由 SQL Server 生成。SQL Server Native Client OLE DB 访问接口将忽略该列绑定的任何值。

VARIANT_TRUE:使用者绑定的取值函数可提供 SQL Server 标识列的值。在接受 NULL 的列上,标识属性不可用,因此使用者为每个 IRowsetFastLoad::Insert 调用提供一个唯一的值。

SSPROP_FASTLOADKEEPNULLS

列:无

R/W:读/写

类型:VT_BOOL

默认值:VARIANT_FALSE

说明:对于有 DEFAULT 约束的列,将保持 NULL。仅影响接受 NULL 并应用了 DEFAULT 约束的 SQL Server 列。

VARIANT_FALSE:当 SQL Server Native Client OLE DB 访问接口使用者插入一个该列包含 NULL 的行时,SQL Server 将插入该列的默认值。

VARIANT_TRUE:当 SQL Server Native Client OLE DB 访问接口使用者插入一个该列包含 NULL 的行时,SQL Server 将插入 NULL 作为列值。

SSPROP_FASTLOADOPTIONS

列:无

R/W:读/写

类型:VT_BSTR

默认值:无

说明:该属性与 bcp 实用工具的 -h "hint[,...n]" 选项相同。以下字符串可以在将数据大容量复制到表中时作为选项使用。

ORDER(column[ASC | DESC][,...n]):数据文件中数据的排序顺序。如果按照表的聚集索引对加载的数据文件进行排序,将会提高大容量复制性能。

ROWS_PER_BATCH = bb:每批数据的行数(作为 bb)。服务器将按照值 bb 对大容量加载进行优化。默认情况下,ROWS_PER_BATCH 是未知的。

KILOBYTES_PER_BATCH = cc:每批数据的 KB 数(作为 cc)。默认情况下,KILOBYTES_PER_BATCH 是未知的。

TABLOCK:在大容量复制操作期间将获得表级锁定。由于仅在大容量复制操作期间持有锁定会减少对表的锁定争用,因此该选项极大地提高了性能。如果表没有索引并且指定了 TABLOCK,则该表可以同时由多个客户端加载。默认情况下,锁定行为由表选项 table lock on bulk load 确定。

CHECK_CONSTRAINTS:在大容量复制操作期间,将检查对 table_name 的任何约束。默认情况下,忽略约束。

FIRE_TRIGGER:在 SQL Server 2000 中,在启用触发器的情况下,不可能优化日志记录,因为触发器逻辑基于日志记录。在启用触发器情况下的大容量导入操作期间,将禁用所有大容量日志记录优化(包括 BU 锁定)。

但是,从 SQL Server 2005 开始,SQL Server 将使用触发器的行版本控制,并在 tempdb 中的版本存储区内存储行版本。因此,即使是在启用触发器时,也可以进行大容量记录优化。在启用触发器的情况下对有很多行的批数据执行大容量导入之前,可能需要增加 tempdb 的大小。

使用基于文件的大容量复制操作

SQL Server Native Client OLE DB 访问接口实现了 IBCPSession 接口,以公开对 SQL Server 基于文件的大容量复制操作的支持。IBCPSession 接口实现了 IBCPSession::BCPColFmtIBCPSession::BCPColumnsIBCPSession::BCPControlIBCPSession::BCPDoneIBCPSession::BCPExecIBCPSession::BCPInitIBCPSession::BCPReadFmtIBCPSession::BCPWriteFmt 方法。

SQL Server Native Client ODBC 驱动程序

SQL Server Native Client ODBC 驱动程序继续支持以前版本的 SQL Server ODBC 驱动程序所包含的大容量复制操作。有关使用 SQL Server Native Client ODBC 驱动程序进行大容量复制操作的信息,请参阅执行大容量复制操作 (ODBC)