当插入权限被拒绝且ANSI_WARNINGS为OFF时,事务被终止

时间:2013-08-05 16:39:39

标签: c# sql-server tsql

我确定这是预期的行为,我只是想更好地理解它。我发现在以下情况下将事务设置为null:

  1. ANSI_WARNINGS已关闭
  2. 尝试对已拒绝插入权限的表执行插入
  3. 没关系。对我来说似乎很奇怪的是,如果我打开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 = false时的输出:

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

    编辑以简化,如果您只是想在SQL Server Management Studio中运行它,这里也会出现一些重现问题的T-SQL。

    --------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
    -----------------------------
    

1 个答案:

答案 0 :(得分:0)

好吧,我也在msdn上发布了这个问题,但有一个原因:XACT_ABORT设置。看起来像ANSI_WARNINGS和XACT_ABORT遇到的一些错误行为(ANSI_WARNINGS会影响XACT_ABORT行为),我创建了一个Connect问题,这可能无处可去。