如果我在 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 作为一系列个体 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

其他提示

您可以回滚插入。为此,我们首先需要了解两件事

BatchSize

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

假设您有一个包含 10 行的文本文件,第 8 行和第 7 行有一些无效的详细信息。当您批量插入文件而不指定或指定批量 Size 时,10 个文件中的 8 个将被插入到表中。无效行即第 8 个和第 7 个失败并且未插入。

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

根据 MSDN:

最大错误:

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

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

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

希望这能解决这个问题。

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

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top