2013-08-05 35 views
1

我確定它是有意的行爲,我只是想更好地理解它。我看到的是一個交易設置爲空時:當插入權限被拒絕並且ANSI_WARNINGS關閉時事務被終止

  1. ANSI_WARNINGS都關閉
  2. 一種插件,嘗試對其中插入權限被拒絕

表這很好。我覺得奇怪的是,如果我打開ANSI_WARNINGS(移除上面的第一個條件),事務不會設置爲null。

這是爲什麼?讓我知道是否有一些我錯過了的ANSI_WARNINGS文檔可以解釋這一點。

代碼來重現問題:

using System.Data.SqlClient; 
using System; 
public class Program 
{ 
    //CREATE TABLE Junk(Name varchar(12)) 
    //DENY INSERT ON Junk to someUser 

    public static void Main(string[] args) 
    { 
     bool ansi_warnings_off = false; 
     int result; 
     SqlCommand cmd = new SqlCommand(); 

     using (SqlConnection conn = new SqlConnection("Data Source=dbServerName;Initial Catalog=dbName;Persist Security Info=True;User ID=someUser;Password=somePassword;")) 
     { 
      conn.Open(); 
      cmd.Connection = conn; 

      using (var trans = conn.BeginTransaction()) 
      { 
       cmd.Transaction = trans; 

       if (ansi_warnings_off) 
       { 
        cmd.CommandText = "SET ANSI_WARNINGS OFF"; 
        result = cmd.ExecuteNonQuery(); 
        Console.WriteLine("===Result of setting ansi_warnings off = " + result); 
       } 

       try 
       {     
        cmd.CommandText = "INSERT INTO Junk(Name) VALUES ('test')"; 
        result = cmd.ExecuteNonQuery(); 
        Console.WriteLine("===Result of insert = " + result); 
       } 
       catch (Exception e) 
       { 
        Console.WriteLine("===Exception for insert = " + e.Message); 
       } 

       Console.WriteLine("===Transaction is null? " + (cmd.Transaction == null)); 
      } 
      conn.Close(); 
     }//using 
    }//main 
} 

輸出時ansi_warnings_off = TRUE:

===Result of setting ansi_warnings off = -1 
===Exception for insert = The INSERT permission was denied on the object 'Junk', database 'dbName', schema 'dbo'. 
===Transaction is null? True 

輸出時ansi_warnings_off =假:

===Exception for insert = The INSERT permission was denied on the object 'Junk', database 'dbName', schema 'dbo'. 
===Transaction is null? False 

編輯:簡化,這裏的一些T-SQL也會重現這個問題,如果喲你只是想在SQL Server Management Studio中運行它。

--------do this as sa--------- 
CREATE TABLE Junk(Name varchar(12)) 
INSERT INTO Junk(Name) VALUES ('original') 
DENY INSERT ON Junk to dbUser 
--------------------------------- 

--now do the next two as dbUser 

-----update is not attempted---- 
SET ANSI_WARNINGS OFF 
BEGIN TRAN 
INSERT INTO Junk(Name) VALUES ('new') 
update Junk SET Name = 'updated' where Name = 'original' 
COMMIT TRAN 
-------------------------------- 

--------update is done------ 
SET ANSI_WARNINGS ON 
BEGIN TRAN 
INSERT INTO Junk(Name) VALUES ('new') 
update Junk SET Name = 'updated' where Name = 'original' 
COMMIT TRAN 
----------------------------- 

回答

0

好吧,我貼這個問題上msdn過,得到的原因提示:XACT_ABORT設置。看起來像ANSI_WARNINGS和XACT_ABORT遇到的一些錯誤行爲(ANSI_WARNINGS可能會影響XACT_ABORT行爲),我創建了一個Connect問題,這個問題可能不會發生。