我想在SQL CLR触发器中打开/关闭触发器递归。根据{{3}},我必须致电
EXEC sp_dboption '<name of db>', 'recursive triggers', 'true'/'false'
有没有办法知道当前的数据库名称是什么?在创建触发器时,我要求用户选择一个,但我不想将其写在表格中。
此致
答案 0 :(得分:1)
您知道创建触发器时数据库是什么......
CREATE TRIGGER etc
....
GO
DECLARE @db varchar(100)
SET @db = DB_NAME()
EXEC sp_dboption @db, 'recursive triggers', 'true'/'false'
答案 1 :(得分:1)
有一种非常简单的方法可以找到触发SQLCLR触发器的数据库的名称:只需建立与Context Connection的连接并获取Database
属性。您甚至不需要执行查询: - )。
以下内容适用于所有SQLCLR对象类型(存储过程,函数,用户定义的聚合,用户定义的类型和触发器):
string _DatabaseName;
using (SqlConnection _Connection = new SqlConnection("Context Connection = true;"))
{
_Connection.Open();
_DatabaseName = _Connection.Database;
}
就是这样!我只是在SQLCLR触发器中尝试过它,效果很好。
限制触发器触发其他触发器时要记住的另一件事是TRIGGER_NESTLEVEL功能。这在T-SQL触发器中效果更好,其中@@PROCID
的值可用且包含触发器的[object_id]
。因此,在T-SQL触发器中,您可以单独限制每个触发器的递归,但仍允许触发器触发其他表上的其他触发器。
在SQLCLR中仍然可以使用它,但如果没有触发器的名称,则只能限制所有触发器。这意味着,您可以阻止任何触发器在任何表上触发任何其他触发器,包括在同一个表上,但是在允许其他表上的触发器的同时,无法限制仅触发相同的触发器可能会被相关的触发器修改。只需使用Context Connection并通过SELECT TRIGGER_NESTLEVEL();
运行SqlCommand.ExecuteScalar()
。
答案 2 :(得分:0)
我找到了更好的解决方案。
我必须完全避免调用EXEC sp_dboption。相反,我必须创建一个临时表作为标志“无递归”,然后检查触发器开始时表的存在并退出,如果表存在。
为何选择临时表?