【发布时间】:2014-02-23 06:48:26
【问题描述】:
我有一个名为 Prices 的 SQL Server 表,其中包含数万行数据。该表被遗留应用程序大量使用,遗憾的是无法修改(不能添加、删除或修改任何列)。
我的要求是跟踪表何时被修改 (INSERT, UPDATE, or DELETE)。但是,Prices 表没有LastUpdated 列,我无法添加这样的列。此外,我的触发器必须与 SQL Server 2005 兼容。
但是,我可以创建一个额外的表 PricesHistory,它将存储 PriceID、UpdateType 和 LastUpdated 列。
我想将SQL TRIGGER 附加到Prices 表中,该表将INSERT 或UPDATE 在PricesHistory 表中的一行中记录价格的最后更新时间以及触发的操作它。
这是我目前所拥有的,它将检测哪个操作导致触发器触发。但是,我对如何从 inserted 或 deleted 表中 SELECT 以及如何对 PricesHistory 表执行正确的 INSERT/UPDATE 感到困惑。
基本上,所有操作都应检查PriceID 是否已存在于PriceHistory 表中,UPDATE 是否已存在于UpdateType 和LastUpdated 列中。如果PriceID 尚不存在,则应将INSERT 与UpdateType 和LastUpdated 值一起使用。
编辑:一位同事提醒我,inserted 和 deleted 项目是行不是表。这意味着我可以做一个简单的IF EXISTS ... UPDATE ELSE INSERT INTO 子句。这是真的?我的印象是它将是行的表,而不是单个行。
CREATE TRIGGER PricesUpdateTrigger
ON Prices
AFTER INSERT, UPDATE, DELETE
AS
DECLARE @UpdateType nvarchar(1)
DECLARE @UpdatedDT datetime
SELECT @UpdatedDT = CURRENT_TIMESTAMP
IF EXISTS (SELECT * FROM inserted)
IF EXISTS (SELECT * FROM deleted)
SELECT @UpdateType = 'U' -- Update Trigger
ELSE
SELECT @UpdateType = 'I' -- Insert Trigger
ELSE
IF EXISTS (SELECT * FROM deleted)
SELECT @UpdateType = 'D' -- Delete Trigger
ELSE
SELECT @UpdateType = NULL; -- Unknown Operation
IF @UpdateType = 'I'
BEGIN
-- Log an insertion record
END
IF @UpdateType = 'U'
BEGIN
-- Log an update record
END
IF @UpdateType = 'D'
BEGIN
-- Log a deletion record
END
GO
【问题讨论】:
-
Inserted/Updated 不是表!??不适用于 MS SQL Server。也许您的同事正在与 oracle 混合使用。对于 MS SQL Server,它可以是一个只有一行的表,但它是一个表。
-
对不起,我的意思是它是一个单行表。就像你做一个群众
UPDATE或DELETE触发器会为每一行触发。 -
不,触发器按每个操作触发,而不是针对每一行。如果您的操作只是更新插入一行,则它是您的应用程序特定行为。我只是想向观众澄清这一点。
-
你的同事大错特错,插入和删除的表格可以包含多行,然后构建触发器来解决这个问题!
标签: sql-server database tsql sql-server-2005 triggers