SQL CLR 触发器:上下文 DB 的名称
我想在 SQL CLR 触发器中打开/关闭触发器递归。根据 http://www.devx.com/tips/Tip/30031,我必须打电话
EXEC sp_dboption '<name of db>', 'recursive triggers', 'true'/'false'
有没有办法知道当前的数据库名称是什么?创建触发器时,我要求用户选择一个,但我不想将其写在表中。
问候,
I'd like to turn trigger recursion on/off in my SQL CLR trigger. According to http://www.devx.com/tips/Tip/30031, I have to call
EXEC sp_dboption '<name of db>', 'recursive triggers', 'true'/'false'
Is there a way to get to know what the current DB name is? When creating trigger, I ask users to choose one, but I don't want to write it in a table.
Regards,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
有一种非常简单的方法可以找到正在触发 SQLCLR 触发器的数据库的名称:只需建立到上下文连接的连接并获取
Database
属性即可。您甚至不需要执行查询:-)。以下内容应该适用于所有 SQLCLR 对象类型(存储过程、函数、用户定义聚合、用户定义类型和触发器):
就是这样!我刚刚在 SQLCLR 触发器中尝试过它,效果很好。
限制触发器触发其他触发器时要记住的另一件事是 TRIGGER_NESTLEVEL功能。这在 T-SQL 触发器中效果更好,其中
@@PROCID
的值可用并且包含触发器的[object_id]
。因此,在 T-SQL 触发器中,您可以单独限制每个触发器的递归,但仍然允许触发器在其他表上触发其他触发器。在SQLCLR中它仍然可以使用,但是如果没有触发器的名称,您只能限制所有触发器。这意味着,您可以防止任何触发器在任何表(包括同一个表)上触发任何其他触发器,但无法限制仅触发同一个触发器,同时允许在其他表上触发可能会被相关触发器修改。只需使用上下文连接并通过
SqlCommand.ExecuteScalar()
运行SELECT TRIGGER_NESTLEVEL();
。There is a very simple way to find the name of the database in which the SQLCLR Trigger is being fired: just make a connection to the Context Connection and get the
Database
property. You don't even need to execute a query :-).The following should work in all SQLCLR object types (Stored Procedure, Function, User-Defined Aggregate, User-Defined Type, and Trigger):
That's it! I just tried it in a SQLCLR Trigger and it works great.
Another thing to keep in mind for limiting Triggers firing other Triggers is the TRIGGER_NESTLEVEL function. This works better in T-SQL Triggers where the value of
@@PROCID
is available and contains the[object_id]
of the Trigger. So in T-SQL Triggers you can limit the recursion of each trigger individually but still allow Triggers to fire other Triggers on other Tables.In SQLCLR it can still be used, but without the name of the Trigger you can only limit all Triggers. Meaning, you can prevent any Trigger from firing any other Trigger on any Table, including on the same Table, but there is no way to limit the firing of only that same Trigger while allowing Triggers on other tables that might be modified by the Trigger in question. Just use a Context Connection and run
SELECT TRIGGER_NESTLEVEL();
viaSqlCommand.ExecuteScalar()
.当您创建触发器时您就知道数据库是什么......
You know what the database is when you create the trigger...
我找到了更好的解决方案。
我必须完全避免调用 EXEC sp_dboption 。相反,我必须创建一个临时表作为“无递归”标志,然后在触发器开头检查表是否存在,如果表存在则退出。
为什么是临时表?
I've found a better solution.
I have to avoid calling EXEC sp_dboption at all. Instead, I have to create a temp table as a flag "no recursion", then check existing of the table at the beginning of the trigger and exit, if the table exists.
Why temporary table?