我正在尝试将日志写入事务中的另一个数据库,以便即使事务回滚,日志也将继续存在。我读过这个答案,上面写着:
一种可能性是使用 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();
}