开发者社区> 问答> 正文

使用CLR存储过程在事务内部进行TSQL日志记录

我正在尝试将日志写入事务内的另一个数据库,以便即使事务回滚也可以保留该日志。我已经阅读了这个答案,其中说:

一种可能性是使用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存储过程应在所有环境下均适用。

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

更新:

因此工作版本如下所示。非常感谢@ Milney:

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();                    
}

展开
收起
祖安文状元 2020-01-04 15:47:12 690 0
1 条回答
写回答
取消 提交回答
  • 如果您使用:

    Connection.ContextConnection = true;
    
    

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

    2020-01-04 15:47:27
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
PostgresChina2018_赖思超_PostgreSQL10_hash索引的WAL日志修改版final 立即下载
Kubernetes下日志实时采集、存储与计算实践 立即下载
日志数据采集与分析对接 立即下载