1

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

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

1 回答 1

0

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

于 2013-08-16T14:24:07.540 回答