SQL Server:触发如何读取插入,更新,删除的值
我在一个表中有触发器,并且想要在插入,更新或删除行时读取UserId
值。怎么做?下面的代码不工作,我对UPDATED
SQL Server:触发如何读取插入,更新,删除的值
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
请注意,inserted, deleted
的含义与inserted 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
等。
最后,要注意inserted
和deleted
是表并且可以(和确实)包含多个记录。
如果一次插入10条记录,inserted
表将包含所有10条记录。这同样适用于删除表和deleted
表。并且在更新的情况下都是这两个表。
编辑 Examplee触发后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的比用户名以外的东西,使用的FULL OUTER JOIN代替。
得到错误没有updated
动态表。只有inserted
和deleted
。在UPDATE
命令中,旧数据存储在deleted
动态表中,新值存储在inserted
动态表中。
将UPDATE
想象成DELETE/INSERT
组合。
我已将行更改为SELECT @UserId = UserId FROM INSERTED,DELETED,现在我得到错误列名'UserId'。 – Tomas 2011-12-14 14:22:43
下面是创建触发器的语法:
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 ]
}
}
如果您想要使用的更新,你只能用IF UPDATE (column)
部分做到这一点。这是不可能做你所问的。
它也*错误,因为这些表中可能有多行,所以试图读取一个值到一个变量会给你那些行的值之一(哪一个是未定义的)。 – 2011-12-14 14:21:20
除了编写一个认为只有一行将被改变的三角架,这是一个糟糕的做法,您已经使用了隐式连接,这也是一个sql反模式。永远不要使用隐含的连接。现在你有一个你可能不想要的交叉连接。在将隐式连接替换为更好的显式连接之后将近20年编写此类代码是不可原谅的。 – HLGEM 2011-12-14 16:28:06