在配置触发器时更新表中的列时出现错误
Posted
技术标签:
【中文标题】在配置触发器时更新表中的列时出现错误【英文标题】:I am getting error while updating a column in a table on while trigger configured 【发布时间】:2021-11-13 12:32:58 【问题描述】:我收到此错误:
消息 217,级别 16,状态 1,过程 trg_upd,第 7 行 [批处理开始第 0 行] 超出最大存储过程、函数、触发器或视图嵌套级别(限制为 32)。
当我在我的数据库中使用此触发器时:
CREATE TRIGGER trg_upd_inrt
ON [dbo].[tbl_A]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE A
SET [Desc] = CASE i.[Desc]
WHEN 'HR DD' THEN 'HRDD'
WHEN 'H PP' THEN 'HPP'
WHEN 'RPT AR' THEN 'RPTARIN'
WHEN 'APPP PPLE' THEN 'APPLE'
WHEN 'HR DD' THEN 'HRDD'
ELSE Desc
END
FROM tbl_A a
INNER JOIN deleted i ON a.id = i.id
END
【问题讨论】:
所以想想你的触发器是做什么的。您有一个更新表的语句。这将导致您的触发器触发 - 这会更新同一个表。然后导致相同的触发器触发更新同一个表。等等。有一个选项可以禁用此 [触发递归](docs.microsoft.com/en-us/sql/database-engine/configure-windows/… 或者您可以更正逻辑以避免递归。顺便说一句,当 Desc 不包含 5 个值之一时会发生什么?彻底测试。 @SMor ELSE 描述。我不想禁用触发器。我更新代码 您没有阅读链接。禁用触发递归。但是你犯了一个常见的错误。您永远不应该更新不需要更新的行。触发器应该检查以确定它执行的操作是否确实需要执行。当触发器执行时,您会惊讶地发现插入的表可以包含零行。 如果您使用来自another answer 的代码,您真的应该在问题中引用它。 【参考方案1】:不幸的是,SQL Server 并没有让你做你想做的事情变得非常简单。您需要使用 instead of
触发器并更新 all 列:
CREATE TRIGGER trg_upd_inrt ON [dbo].[tbl_A] INSTEAD OF UPDATE
AS BEGIN
SET NOCOUNT ON;
UPDATE A
SET [Desc] = CASE i.[Desc]
WHEN 'HR DD' THEN 'HRDD'
WHEN 'H PP' THEN 'HPP'
WHEN 'RPT AR' THEN 'RPTARIN'
WHEN 'APPP PPLE' THEN 'APPLE'
WHEN 'HR DD' THEN 'HRDD'
ELSE i.[Desc]
END,
COL1 = i.Col1,
COL2 = i.Col2,
. . . -- all the rest of the columns that might be updated
FROM tbl_A a INNER JOIN
inserted i
ON a.id = i.id ;
END;
请注意,这使用 new 值而不是 old 值进行替换。这对我来说很有意义。由于表别名,我假设您确实打算使用inserted
而不是deleted
。
如果您确实需要这两个值,只需将两者都包含在 FROM
子句中:
FROM tbl_A a INNER JOIN
inserted i
ON a.id = i.id INNER JOIN
deleted d
ON d.id = d.id
【讨论】:
以上是关于在配置触发器时更新表中的列时出现错误的主要内容,如果未能解决你的问题,请参考以下文章