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

Posted

技术标签:

【中文标题】SQL Server 批量插入是事务性的吗?【英文标题】:Is SQL Server Bulk Insert Transactional? 【发布时间】:2010-09-07 16:45:40 【问题描述】:

如果我在 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 的方式是否使其不是事务性的,或者我是否需要做一些明确的事情来强制它在失败时回滚?

【问题讨论】:

【参考方案1】:

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

【讨论】:

【参考方案2】:

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

【讨论】:

如果要插入大量行,请注意事务日志被填满等情况。【参考方案3】:

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

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

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

【讨论】:

【参考方案4】:

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

BatchSize

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

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

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

根据 MSDN:

最大错误数:

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

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

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

希望这能解决问题。

【讨论】:

使用 BatchSize=1 而不是单独的 INSERT 语句有什么意义? 我认为批量大小 =1 提交的事务与单个插入语句相同,但后者需要一些循环和行号才能插入而不重复。同意您的说法,但可以在 BULK INSERT 属性的帮助下完成

以上是关于SQL Server 批量插入是事务性的吗?的主要内容,如果未能解决你的问题,请参考以下文章

MyCat批量插入

Python批量插入问题?

SQL中用循环批量插入数据如何实现

sql server有批量插入和批量更新的sql语句吗

Oracle 批量插入数据怎么做

在 SQL Server CE 中批量插入