web-dev-qa-db-ja.com

SQL Server:挿入、更新、削除の値の読み取り方法をトリガーします

1つのテーブルにトリガーがあり、行が挿入、更新、または削除されたときにUserId値を読み取りたい。どうやってするか?以下のコードは機能しません。UPDATEDでエラーが発生します

ALTER TRIGGER [dbo].[UpdateUserCreditsLeft] 
   ON  [dbo].[Order]
   AFTER INSERT,UPDATE,DELETE
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    DECLARE 
    @UserId INT,

    SELECT @UserId = INSERTED.UserId FROM INSERTED, DELETED

    UPDATE dbo.[User] SET CreditsLeft = CreditsLeft - 1 WHERE Id = @UserId
END
17
Tomas

inserted, deletedinserted CROSS JOIN deletedと同じことを意味し、すべての行のすべての組み合わせを提供することに注意してください。私はこれがあなたが望んでいることを疑います。

このような何かがあなたを始めるのに役立つかもしれません...

SELECT
  CASE WHEN inserted.primaryKey IS NULL THEN 'This is a delete'
       WHEN  deleted.primaryKey IS NULL THEN 'This is an insert'
                                        ELSE 'This is an update'
  END  as Action,
  *
FROM
  inserted
FULL OUTER JOIN
  deleted
    ON inserted.primaryKey = deleted.primaryKey


目的に応じて、inserted.userIDまたはdeleted.userIDなどを使用して、関心のあるテーブルを参照します。


最後に、inserteddeletedtablesであり、複数のレコードを含むことができる(そして実際に行う)ことに注意してください。

一度に10個のレコードを挿入すると、insertedテーブルには10個すべてのレコードが含まれます。同じことが削除とdeletedテーブルにも当てはまります。そして、更新の場合の両方のテーブル。


[〜#〜] edit [〜#〜] OPの編集後の例のトリガー。

ALTER TRIGGER [dbo].[UpdateUserCreditsLeft] 
  ON  [dbo].[Order]
  AFTER INSERT,UPDATE,DELETE
AS 
BEGIN

  -- SET NOCOUNT ON added to prevent extra result sets from
  -- interfering with SELECT statements.
  SET NOCOUNT ON;

  UPDATE
    User
  SET
    CreditsLeft = CASE WHEN inserted.UserID IS NULL THEN <new value for a  DELETE>
                       WHEN  deleted.UserID IS NULL THEN <new value for an INSERT>
                                                    ELSE <new value for an UPDATE>
                  END
  FROM
    User
  INNER JOIN
    (
      inserted
    FULL OUTER JOIN
      deleted
        ON inserted.UserID = deleted.UserID  -- This assumes UserID is the PK on UpdateUserCreditsLeft
    )
      ON User.UserID = COALESCE(inserted.UserID, deleted.UserID)

END


UpdateUserCreditsLeftのPrimaryKeyがUserID以外の場合、代わりにFULL OUTER JOINでそれを使用します。

29
MatBailie

updated動的テーブルはありません。inserteddeletedのみがあります。 UPDATEコマンドでは、古いデータはdeleted動的テーブルに保存され、新しい値はinserted動的テーブルに保存されます。

UPDATEDELETE/INSERTの組み合わせと考えてください。

24
user596075