18

如果我在 SQL Server 2000 查询分析器中运行以下查询:

BULK INSERT  OurTable 
FROM 'c:\OurTable.txt' 
WITH (CODEPAGE = 'RAW', DATAFILETYPE = 'char', FIELDTERMINATOR = '\t', ROWS_PER_BATCH = 10000, TABLOCK)

在符合 OurTable 架构的 40 行文本文件上,但随后更改了最后 20 行的格式(假设最后 20 行的字段较少),我收到一个错误。但是,前 40 行已提交到表中。我调用 Bulk Insert 的方式是否使它不是事务性的,或者我是否需要做一些明确的事情来强制它在失败时回滚?

4

4 回答 4

25

BULK INSERT充当一系列单独的INSERT语句,因此,如果作业失败,它不会回滚所有已提交的插入。

但是,它可以放置在事务中,因此您可以执行以下操作:

BEGIN TRANSACTION
BEGIN TRY
BULK INSERT  OurTable 
FROM 'c:\OurTable.txt' 
WITH (CODEPAGE = 'RAW', DATAFILETYPE = 'char', FIELDTERMINATOR = '\t', 
   ROWS_PER_BATCH = 10000, TABLOCK)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
于 2008-09-30T11:50:58.193 回答
3

您可以回滚插入。要做到这一点,我们首先需要了解两件事

BatchSize

: 每个事务要插入的行数。默认为整个数据文件。所以一个数据文件在事务中

假设您有一个文本文件,其中有 10 行和第 8 行,第 7 行有一些无效的详细信息。当您在不指定或指定批量大小的情况下批量插入文件时,十分之八的文件会插入到表中。Invalid Row's ie 8th 和 7th 失败并且没有被插入。

发生这种情况是因为默认MAXERRORS计数为每笔交易 10。

根据 MSDN:

最大错误:

指定取消批量导入操作之前数据中允许的最大语法错误数。无法通过批量导入操作导入的每一行都将被忽略并计为一个错误。如果未指定 max_errors,则默认值为 10。

因此,为了使所有 10 行都失败,即使其中一行无效,我们也需要设置MAXERRORS=1这里BatchSize=1BatchSize 的数量也很重要。

如果您指定 BatchSize 并且无效行在特定批次内,它将仅回滚特定批次,而不是整个数据集。所以在选择这个选项时要小心

希望这能解决问题。

于 2016-12-22T13:55:25.807 回答
1

BATCHSIZEMSDN 库 ( http://msdn.microsoft.com/en-us/library/ms188365(v=sql.105).aspx ) 中 BULK INSERT 的定义所述:

“如果失败,SQL Server 会为每个批次提交或回滚事务......”

总之,没有必要向批量插入添加事务性。

于 2012-03-01T17:09:45.843 回答
0

尝试将其放入用户定义的事务中,看看会发生什么。实际上它应该按照您的描述回滚。

于 2008-09-03T15:30:53.593 回答