1

我正在尝试将日志写入事务中的另一个数据库,以便即使事务回滚,日志也将继续存在。我读过这个答案,上面写着:

一种可能性是使用 CLR 存储过程进行日志记录。这可以在事务之外打开自己与数据库的连接,并输入和提交日志数据。

所以我使用这篇文章创建了 CLR 存储过程:

[SqlProcedure]
public static void Voice(SqlString procedureName, SqlInt32 id)
{
    Connection = new SqlConnectionStringBuilder();
    Connection.ContextConnection = true;

    using (TransactionScope transScope = new TransactionScope())
    {                
        using (SqlConnection conn = new SqlConnection(Connection.ToString()))
        {
            conn.Open();                    
            SqlCommand cmdInsert = conn.CreateCommand();
            cmdInsert.CommandText = sql;
            cmdInsert.Parameters.Add("@id", SqlDbType.Int);
            cmdInsert.Parameters[0].Value = id;         
            cmdInsert.Parameters.Add("@procedureName", SqlDbType.NVarChar);
            cmdInsert.Parameters[1].Value = procedureName;
            cmdInsert.ExecuteNonQuery();                
        }
        transScope.Complete();
    }
}

但是,我在 SQL Server 中执行和回滚存储过程后,并没有保存数据:

BEGIN TRAN
    EXEC dbo.SayHelloVoice @id = 1,
                           @procedureName = N'FooProcedure'
ROLLBACK TRAN

我们有三个环境:

  • dev. 服务器名称是Q-SQL001
  • test. 服务器名称是Q-SQL002
  • prod. 服务器名称是Q-SQL003

所以这个 CLR 存储过程应该适用于所有环境。

你能说我做错了什么吗?任何帮助将不胜感激!

更新:

所以工作版本看起来像这样。非常感谢@米尔尼

var serverName = string.Empty;
var dbName = string.Empty;
serverName = SqlExecuteScalar("SELECT @@SERVERNAME");
dbName = SqlExecuteScalar("SELECT DB_NAME()");

SqlConnectionStringBuilder sqlConn = new SqlConnectionStringBuilder();
sqlConn.InitialCatalog = dbName;
sqlConn.DataSource = serverName;
sqlConn.IntegratedSecurity = true;
sqlConn.ContextConnection = false;
sqlConn.Enlist = false;
sqlConn.ApplicationName = "New application";

var sql = "USE FooDatabase
           INSERT INTO dbo.MyTable ..."
using (SqlConnection conn2 = new SqlConnection(sqlConn.ConnectionString))
{
    conn2.Open();                    
    SqlCommand cmdInsert = conn2.CreateCommand();
    cmdInsert.CommandText = sql;
    cmdInsert.Parameters.Add("@id", SqlDbType.Int);
    cmdInsert.Parameters[0].Value = storeTime;
    cmdInsert.Parameters.Add("@messageText", SqlDbType.NVarChar);
    cmdInsert.Parameters[1].Value = messageText;            
    cmdInsert.ExecuteNonQuery();                    
} 
4

1 回答 1

3

如果您使用:

Connection.ContextConnection = true;

然后它将使用运行 CLR Sproc 的相同连接 - 您需要打开一个连接。

于 2019-12-27T09:57:34.827 回答