【问题标题】:MERGE leads to 'Subquery returned more than 1 value' error in triggerMERGE 导致触发器中的“子查询返回超过 1 个值”错误
【发布时间】:2013-03-20 21:32:24
【问题描述】:

下面是表上的触发器和我用于更新的查询。

触发器

此触发器将根据插入或更新到另一列的文本更新 Type ID 列...这是为了在设计不佳的表上强制输入

CREATE TRIGGER [dbo].[TypeIDInsert] 
    ON [dbo].[Table1]
    AFTER INSERT, UPDATE
AS
BEGIN

    IF (SELECT TypeID FROM inserted) IS NULL
    BEGIN

        DECLARE @ID [int] = (SELECT ID FROM inserted);

        UPDATE Table1 SET TypeID = (
            CASE TypeName
                WHEN 'Value 1' THEN 1
                WHEN 'Value 2' THEN 2
                WHEN 'Value 3' THEN 3
                ELSE 0
            END
        )
        WHERE ID = @ID

    END

END

ID 列是 IDENTITY 列。

更新声明

MERGE INTO Table1
    USING Table1TypeTable
        ON Table1.TypeName= TypeTable.TypeName
WHEN MATCHED THEN
    UPDATE SET TypeID = TypeTable.TypeID;

当触发器被启用时,我得到了错误:

子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。

我发现这篇帖子 Update statement error: Subquery returned more than 1 value 描述了问题是表上的触发器一次只为一条记录设计。我禁用了触发器并能够成功进行更新。我的问题是如何编写触发器,以免在这样的大规模更新中引起问题。

【问题讨论】:

  • 是的,您的触发器假定所有操作只影响一行!
  • 我明白了,重新格式化此触发器以不假设的最佳方法是什么?

标签: sql-server-2008 triggers merge sql-update


【解决方案1】:

有几件事:您的触发器假设所有操作只影响一行。这样做的方法是将 join 插入到插入的表中,而不是尝试用谁知道哪一行的 ID 值填充单个变量。此外,检查inserted(在您的示例中缺少EXISTS)并不是真正必要的。如果inserted 中有 0 行,则无论如何都不会执行更新。

ALTER TRIGGER [dbo].[TypeIDInsert] 
    ON [dbo].[Table1]
    AFTER INSERT, UPDATE
AS
BEGIN
  SET NOCOUNT ON;

  UPDATE t SET t.TypeID = CASE i.TypeName
      WHEN 'Value 1' THEN 1
      WHEN 'Value 2' THEN 2
      WHEN 'Value 3' THEN 3
      ELSE 0 END
    FROM dbo.Table1 AS t
    INNER JOIN inserted AS i
    ON t.ID = i.ID;
END
GO

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 2014-03-11
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    相关资源
    最近更新 更多