0

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

扳机

此触发器将根据插入或更新到另一列的文本更新类型 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 个值。当子查询跟随 =、!=、<、<=、>、>= 或子查询用作表达式时,这是不允许的。

我发现这篇文章更新语句错误:子查询返回超过 1 个值,描述问题是表上的触发器一次只为一条记录设计。我禁用了触发器并能够成功进行更新。我的问题是如何编写触发器,以免在这样的大规模更新中引起问题。

4

1 回答 1

1

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

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
于 2013-03-20T21:37:49.853 回答