如果我在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的方式使它不是事务性的,或者我是否需要做一些明确的事情来强制它在失败时回滚?
答案 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=1
和BatchSize=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)
尝试将其置于用户定义的事务中,看看会发生什么。实际上它应该像你描述的那样回滚。