2011-02-14 45 views
2

我有以下回滚没有发生......为什么?

Declare @tbl Table(Id int identity, SomeCol varchar(10) not null) 

Begin Transaction Tran1 
    Declare @ErrorNum int 
    Declare @i int 
    Set @i =1 

    --Start Operation 
    While(@i <= 10) 
    Begin 

     If(@i = 9) 
      Begin 
       Insert into @tbl(SomeCol) Values(null) 
       Set @ErrorNum = @@ERROR 
      End 
     Else 
      -- All records will be inserted successfully 
      Begin 
       Insert into @tbl(SomeCol) Values(@i) 
      End 
     Set @i = @i +1 

    End -- End of while 

    -- If there is any error, notify that and roll back the transaction 
    IF @ErrorNum <> 0 
    BEGIN 
     RAISERROR ('Attempt to insert null value in [Phone Number] is not allowed',16,1) 
     Rollback Transaction Tran1 
    End 
IF (@ErrorNum = 0) 
    COMMIT TRANSACTION Tran1 

    select * from @tbl 

我所试图做的是,如果@i的值是9,我试图插入一个空值的@tbl这不应该让所有和应该回滚所有记录并只会生成自定义异常。

但它给出了系统和自定义异常,并且记录已被插入,而不是回滚,除了第9条记录。

下面是我在邮件选项卡

**(1 row(s) affected) 
(1 row(s) affected) 
(1 row(s) affected) 
(1 row(s) affected) 
(1 row(s) affected) 
(1 row(s) affected) 
(1 row(s) affected) 
(1 row(s) affected) 
Msg 515, Level 16, State 2, Line 14 
Cannot insert the value NULL into column 'SomeCol', table '@tbl'; column does not allow nulls. INSERT fails. 
The statement has been terminated. 
(1 row(s) affected) 
Msg 50000, Level 16, State 1, Line 29 
Attempt to insert null value in SomeCol is not allowed 
(9 row(s) affected)** 

GOT和下面是在记录片

Id SomeCol 
1 1 
2 2 
3 3 
4 4 
5 5 
6 6 
7 7 
8 8 
10 10 

我不知道自己做错了什么我做了。

需要帮助。

回答

2

表变量不会回滚。尝试使用#temporary表,而您的脚本应该按预期工作!

create Table #tbl(Id int identity, SomeCol varchar(10) not null) 

Begin Transaction Tran1 
    Declare @ErrorNum int 
    Declare @i int 
    Set @i =1 

    --Start Operation 
    While(@i <= 10) 
    Begin 

     If(@i = 9) 
      Begin 
       Insert into #tbl(SomeCol) Values(null) 
       Set @ErrorNum = @@ERROR 
      End 
     Else 
      -- All records will be inserted successfully 
      Begin 
       Insert into #tbl(SomeCol) Values(@i) 
      End 
     Set @i = @i +1 

    End -- End of while 

    -- If there is any error, notify that and roll back the transaction 
    IF @ErrorNum <> 0 
    BEGIN 
     RAISERROR ('Attempt to insert null value in [Phone Number] is not allowed',16,1) 
     Rollback Transaction Tran1 
    End 
IF (@ErrorNum = 0) 
BEGIN 
    PRINT 'COMMIT' 
    COMMIT TRANSACTION Tran1 
END 
    select * from #tbl 

drop table #tbl 
+0

这很好..我现在用#temp表。它的工作。但我只想生成自定义消息。我得到(1 row(s)affected) .... (1 Msg 515,Level 16,State 2,Line 14 不能将值NULL插入'SomeCol'列'tempdb.dbo。#tbl'__________________________________________________________________________ 00000000000C ';列不允许为空,INSERT失败 该语句已被终止。 (1行(一个或多个)受影响) 消息50000,级别16,状态1,行30 尝试中插入空值[电话号码]不允许 (影响0行(S)) – user1 2011-02-14 13:43:56

+0

@user。不知道在2000年是否/如何抑制这种情况。以后的版本可以使用`TRY ... CATCH` – 2011-02-14 13:48:27

0

看起来,你是永远不会 Rollback Transaction Tran1 - 因为RAISE之前出现。 只是交换两条线

0

如果您添加以下脚本,那么整个交易将失败(否部分加载表变量)回滚的开头,但你可能看不到您的自定义错误消息:

SET XACT_ABORT ON 

从微软documentation

当SET XACT_ABORT为OFF时,在某些情况下, 只引发错误的Transact-SQL语句 回滚 和交易继续 处理。根据错误的严重程度 ,当SET XACT_ABORT为OFF时,整个 事务可能会回退,即使在 也是如此。 OFF是默认设置 。

如果你想成为rolledback并发布你的自定义错误讯息支付,你可以使用的try ... catch交易:

BEGIN TRY 
    Declare @tbl Table(Id int identity, SomeCol varchar(10) not null) 

    Begin Transaction Tran1 
     Declare @i int 
     Set @i =1 

     --Start Operation 
     While(@i <= 10) 
     Begin 

      If(@i = 9) 
       Begin 
        Insert into @tbl(SomeCol) Values(null) 
       End 
      Else 
       -- All records will be inserted successfully 
       Begin 
        Insert into @tbl(SomeCol) Values(@i) 
       End 
      Set @i = @i +1 

     End -- End of while 

     COMMIT TRANSACTION Tran1 

     select * from @tbl 
END TRY 
BEGIN CATCH 
     BEGIN 
      RAISERROR ('Attempt to insert null value in [Phone Number] is not allowed',16,1) 
      Rollback Transaction Tran1 
     End 
END CATCH