2008-09-03 181 views
14

如果我运行在SQL Server以下查询2000查询分析器:SQL Server批量插入事务?

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

在符合OurTable的架构40行的文本文件,但后来改变格式的最后20行(可以说是近20行数少的字段),我收到一个错误。但是,前40行致力于表格。有没有关于我调用批量插入的方式,使它不是事务性的,还是我需要做一些明确的事情来强制它在失败时回滚?

回答

18

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 
+2

如果插入很多行,请注意事务日志已满。 – 2010-01-26 09:54:34

0

试着把它放在用户定义的事务中,看看会发生什么。事实上,它应该像你描述的那样回滚。

2

正如BATCHSIZE定义为MSDN库BULK INSERT(http://msdn.microsoft.com/en-us/library/ms188365(v=sql.105).aspx)指出:

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

总而言之,没有必要为Bulk Insert添加事务性。

+0

[Microsoft documentation suckzz !!](http://technet.microsoft.com/es-es/library/ms188365.aspx)两天的测试,最后我注意到BULK INSERT不支持编译级事务错误的回滚。我的意思是你需要为批量插入查询创建一个存储过程,然后用“try/catch”包围exec your_procedure。 MAXERRORS = 0立即捕获第一个错误也很重要。 – 2012-03-08 06:54:42

2

您可以回滚插入。要做到这一点,我们需要明白两两件事第一

BatchSize

:没有行的每次交易插入。默认为全部 数据文件。所以一个数据文件在交易

假设你有一个文本文件有10行和第8行和第7行有一些无效的细节。当您批量插入文件时未指定或指定批量大小时,将有8个插入到表格中。无效行即第8和第7行失败并且未被插入。

这会发生,因为默认MAXERRORS计数是每笔交易10。

按照MSDN:

MAXERRORS:

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

所以中序失败的所有10行,即使一个是无效的,我们需要设置MAXERRORS=1BatchSize=1这里BATCHSIZE的数量也很重要。

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

希望这可以解决这个问题。

+0

BatchSize = 1而不是单独的INSERT语句有什么意义? – proteus 2018-01-25 00:02:31