SQL Server:触发如何读取Insert,Update,Delete的值

时间:2011-12-14 14:16:33

标签: sql sql-server triggers

我在一个表中有触发器,并希望在插入,更新或删除行时读取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

3 个答案:

答案 0 :(得分:29)

请注意,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.userIDdeleted.userID等参考您感兴趣的表格。


最后,请注意inserteddeleted,并且可以(并且确实)包含多条记录。

如果一次插入10条记录,inserted表将包含所有10条记录。这同样适用于删除和deleted表。并且在更新的情况下都是两个表。


编辑示例在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中使用它。

答案 1 :(得分:23)

没有updated动态表。只有inserteddeleted。在UPDATE命令中,旧数据存储在deleted动态表中,新值存储在inserted动态表中。

UPDATE视为DELETE/INSERT组合。

答案 2 :(得分:-4)

以下是创建触发器的语法:

CREATE TRIGGER trigger_name
ON { table | view }
[ WITH ENCRYPTION ]
{
    { { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] }
        [ WITH APPEND ]
        [ NOT FOR REPLICATION ]
        AS
        [ { IF UPDATE ( column )
            [ { AND | OR } UPDATE ( column ) ]
                [ ...n ]
        | IF ( COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask )
                { comparison_operator } column_bitmask [ ...n ]
        } ]
        sql_statement [ ...n ]
    }
} 

如果您想使用On Update,则只能使用IF UPDATE ( column )部分。那是不可能做你要求的。