如果查询完成但有错误,是否需要回滚?

时间:2012-01-24 17:21:48

标签: sql sql-server sql-server-2008

我有这样的查询:

use DataIncremental
go
DECLARE @row_terminator CHAR;
SET @row_terminator = CHAR(10); -- or char(10)

BEGIN TRAN tran2


DECLARE @stmt NVARCHAR(2000);
SET @stmt = '
  BULK INSERT accn_adjustments
   FROM ''C:\Users\agordon\Desktop\incrementaljan2012\accn_adjustments_201112302112.txt''
   WITH 
      (
        firstrow=2,
FIELDTERMINATOR = ''|''  ,
ROWS_PER_BATCH=10000
   ,ROWTERMINATOR='''+@row_terminator+'''
   )'
exec sp_executesql @stmt;
SET @stmt = '
  BULK INSERT accn_adjustments
   FROM ''C:\Users\agordon\Desktop\incrementaljan2012\accn_adjustments_201112312112.txt''
   WITH 
      (
        firstrow=2,
FIELDTERMINATOR = ''|''  ,
ROWS_PER_BATCH=10000
   ,ROWTERMINATOR='''+@row_terminator+'''
   )'
exec sp_executesql @stmt;
SET @stmt = '
  BULK INSERT accn_adjustments
   FROM ''C:\Users\agordon\Desktop\incrementaljan2012\accn_adjustments_201201022101.txt''
   WITH 
      (
        firstrow=2,
FIELDTERMINATOR = ''|''  ,
ROWS_PER_BATCH=10000
   ,ROWTERMINATOR='''+@row_terminator+'''
   )'
exec sp_executesql @stmt;
SET @stmt = '
  BULK INSERT accn_adjustments
   FROM ''C:\Users\agordon\Desktop\incrementaljan2012\accn_adjustments_201201032101.txt''
   WITH 
      (
        firstrow=2,
FIELDTERMINATOR = ''|''  ,
ROWS_PER_BATCH=10000
   ,ROWTERMINATOR='''+@row_terminator+'''
   )'
exec sp_executesql @stmt;

我提出begin tran tran2的原因是为了确保如果有错误我可以做rollback

我运行了代码,我得到的消息是"query completed with errors"

SSMS并没有像往常那样陈述一些rows were inserted

当我尝试rollback tran tran2时,它表示该交易从未开始

所以我的问题是,是否已提交到数据库的行?

如果没有,那么为什么它说“查询已完成但有错误”,它是否因为错误而导致查询未完成?

2 个答案:

答案 0 :(得分:2)

描述

自SQL Server 2005起,您可以使用TRY CATCH

来处理错误
  

TRY ... CATCH(Transact-SQL)实现Transact-SQL的错误处理,类似于Microsoft Visual C#和Microsoft Visual C ++语言中的异常处理。一组Transact-SQL语句可以包含在TRY块中。如果TRY块中发生错误,则控制权将传递给CATCH块中包含的另一组语句。

示例

BEGIN TRY
    BEGIN TRANSACTION

     -- do something

    COMMIT TRAN -- Transaction successfull, commit!
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRAN --RollBack if error occured
END CATCH

更多信息

答案 1 :(得分:1)

来自the documentation on BULK INSERT

  

BULK INSERT语句可以在用户定义的内执行   交易。回滚使用BULK的用户定义事务   INSERT语句和BATCHSIZE子句将数据导入表或   使用多个批处理的视图回滚发送到SQL Server的所有批处理。

sp_executesql包含在最外层的事务(以BEGIN TRANSACTION开头的事务)中,因此这些批量插入应该都是事务性的。

正如@ MartinSmith的评论所暗示的那样,如果XACT_ABORT运行时间过长,XACT_ABORT可能会中止这个最外层的交易。