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;

トリガーを有効にすると、次のエラーが表示されます。

サブクエリが複数の値を返しました。サブクエリが =、!=、<、<=、>、>= の後にある場合、またはサブクエリが式として使用されている場合、これは許可されません。

この投稿Update statement error: Subquery returned more than 1 valueを見つけました。これは、テーブルのトリガーが一度に 1 つのレコードに対してのみ設計されていることが問題であることを示しています。トリガーを無効にして、更新を正常に行うことができました。私の質問は、このような一括更新で問題が発生しないようにトリガーを作成する方法です。

4

1 に答える 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 に答える