Dan*_*ana 7 trigger sql-server t-sql
我已经使用 SQL 查询几个星期了,我正在尝试从错误中学习和理解。我有两列的表IsInvisible (bit)
和ShortName (string)
当一个被改变为更新的另一个也如: -如果添加〜于SHORTNAME到组的前面IsInvisible
为1,并且如果〜被去除,以将其设置为0 -如果IsInvisible
被设置为1 在 ShortName 前面添加 ~ 并在设置为 0 时将其删除。
我试过这样的事情:
ALTER TRIGGER [dbo].[updateInvisibility]
ON [dbo].[table]
AFTER UPDATE
AS
BEGIN
UPDATE t
SET IsInvisible = (CASE WHEN i.ShortName like '~%' THEN 1 ELSE 0 END),
ShortName = (CASE WHEN i.IsInvisible = 1 AND t.ShortName NOT LIKE '~%'
THEN '~' + t.ShortName
ELSE t.ShortName
END)
FROM table t JOIN
inserted i
ON t.Id = i.Id;
end
Run Code Online (Sandbox Code Playgroud)
我的问题是,当我更新其中一列或同时更新两列时,没有任何反应,并且出现此错误:
Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32)
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
“允许触发器触发其他人”选项显示“真”。
小智 10
这是问题所在:
updateInvisibility
updateInvisibility
触发器然后它一直这样做,所以你最终以一种递归的方式多次触发触发器,甚至没有意识到。SQL Server 将允许此调用嵌套深度为 32 级,然后抛出此错误:
超出最大存储过程、函数、触发器或视图嵌套级别(限制 32)
这是很清楚的。
纯代码解决方案是检查嵌套级别,如果大于 1 则离开(1 是第一次被更新调用):
IF TRIGGER_NESTLEVEL() > 1 RETURN;
Run Code Online (Sandbox Code Playgroud)
像这样:
ALTER TRIGGER [dbo].[updateInvisibility]
ON [dbo].[table]
AFTER UPDATE
AS
BEGIN
IF TRIGGER_NESTLEVEL() > 1 RETURN;
-- Do your work...
END
Run Code Online (Sandbox Code Playgroud)
正如RBarryYoung在评论中指出的那样,您可以首先通过禁用递归触发器来防止此问题。
归档时间: |
|
查看次数: |
716 次 |
最近记录: |