SQL Server批量插入是否是事务性的?

时间:2008-09-03 15:01:54

标签: sql-server transactions bulkinsert

如果我在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 个答案:

答案 0 :(得分:21)

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

答案 1 :(得分:3)

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

  

BatchSize

     

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

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

这种情况会发生,因为每次交易的默认MAXERRORS计数为10。

按照MSDN:

  

MAXERRORS:

     

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

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

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

希望这可以解决问题。

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:0)

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