[英]Updated Value in SQL Server specially in SQL server 2005
如何在SQL Server 2005中专门在触发器中检测更新的值?
请注意,您不应尝试获取该值,因为应将触发器编码为处理多个行更改
也就是说,您可以使用特殊的DELETED和INSERTED表
CREATE TRIGGER TRG_SomeTable_U ON dbo.SomeTable AFTER UPDATE
AS
-- DECLARE @ TABLE ...
-- INSERT HistoryTable
-- whatever
SELECT
...
FROM
INSERTED I
JOIN
UPDATED U ON I.PK 0 U.PK
WHERE
I.SomeColumn <> U.SomeColumn -- does not handle NULLs
GO
最简单的解决方案使用触发器。 看一下他的例子。 也许会帮助您。 另外,您可以在源代码中找到一些注释。
--Test initialization
CREATE TABLE dbo.[Transaction]
(
ID INT IDENTITY(1,1) PRIMARY KEY,
InsertDateTime DATETIME NOT NULL DEFAULT GETDATE(),
[Date] DATETIME,
CustomerID VARCHAR(50),
[Type] VARCHAR(3),
Amount MONEY
);
GO
INSERT INTO [Transaction]([Date],CustomerID,[Type],Amount)
SELECT '2011-01-01','CUST1001','INV','12,000' UNION ALL
SELECT '2011-01-02','CUST1001','PAY','3,000' UNION ALL
SELECT '2011-01-03','CUST1001','INV','8,000' UNION ALL
SELECT '2011-01-04','CUST1001','PAY','9,000' UNION ALL
SELECT '2011-01-04','CUST1002','INV','1,000' UNION ALL
SELECT '2011-01-05','CUST1002','PAY','5,000' UNION ALL
SELECT '2011-01-05','CUST1002','INV','6,000';
GO
CREATE TABLE AuditTransaction
(
AuditID INT IDENTITY(1,1) PRIMARY KEY
,UpdateDateTime DATETIME NOT NULL DEFAULT GETDATE()
,ID INT NOT NULL
,[Date] DATETIME NULL
,CustomerID VARCHAR(50) NULL
,[Type] VARCHAR(3) NULL
,Amount MONEY NULL
);
GO
CREATE TRIGGER trgI_Transaction_Logging
ON dbo.[Transaction]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
--Will be inserted only the old values (d.* = deleted.*) . Otherwise NULL will be inserted.
INSERT dbo.AuditTransaction(ID,[Date],CustomerID,[Type],Amount)
SELECT i.ID
--If the old value (d.[Date]) and the new one (i.[Date]) are both equals
--then "NULL"
--else "old value" (d.[Date])
,NULLIF(d.[Date],i.[Date])
,NULLIF(d.CustomerID,i.CustomerID)
,NULLIF(d.[Type],i.[Type])
,NULLIF(d.Amount,i.Amount)
FROM deleted d INNER JOIN inserted i ON d.ID=i.ID;
END;
GO
--End of Test initialization
--Test: run UPDATEs
WAITFOR DELAY '00:00:01';
UPDATE dbo.[Transaction]
SET Amount = Amount + 5
WHERE ID = 1;
--1 second delay between UPDATEs
WAITFOR DELAY '00:00:01';
UPDATE dbo.[Transaction]
SET Amount = Amount + 9
,[Date] = '2011-01-02 22:22:22'
WHERE ID = 2;
WAITFOR DELAY '00:00:01';
UPDATE dbo.[Transaction]
SET Amount = Amount + 9
,[Date] = '2011-01-02 11:11:11'
WHERE ID = 1;
WAITFOR DELAY '00:00:01';
UPDATE dbo.[Transaction]
SET Amount = Amount + 10
WHERE ID = 3;
WAITFOR DELAY '00:00:01';
UPDATE dbo.[Transaction]
SET Amount = Amount + 20
WHERE ID = 4;
WAITFOR DELAY '00:00:01';
UPDATE dbo.[Transaction]
SET CustomerID = NULL
WHERE ID = 5;
--End of UPDATEs
PRINT 'dbo.AuditTransaction content'
SELECT *
FROM dbo.AuditTransaction at;
--Test: checking ”log” (audit table) for the first transaction
DECLARE @TransactioID INT;
SELECT @TransactioID = 1;
PRINT 'Transaction 1 history'
SELECT 'I' AS OperationType, t.[InsertDateTime] OperationDateTime, 0 AS AuditID
,t.ID, t.[Date], t.CustomerID, t.[Type], t.Amount
FROM dbo.[Transaction] t
WHERE t.ID = @TransactioID
UNION ALL
SELECT 'U' AS OperationType, at.UpdateDateTime, at.AuditID
,at.ID, at.[Date], at.CustomerID, at.[Type], at.Amount
FROM dbo.AuditTransaction at
WHERE at.ID = @TransactioID
ORDER BY OperationType DESC, OperationDateTime;
--End of test
--By, by
DROP TABLE dbo.AuditTransaction;
DROP TABLE dbo.[Transaction];
GO
结果:
dbo.AuditTransaction content
AuditID UpdateDateTime ID Date CustomerID Type Amount
----------- ----------------------- ----------- ----------------------- -------------------------------------------------- ---- ---------------------
1 2011-10-02 13:48:22.683 1 NULL NULL NULL 12000,00
2 2011-10-02 13:48:23.677 2 2011-01-02 00:00:00.000 NULL NULL 3000,00
3 2011-10-02 13:48:24.680 1 2011-01-01 00:00:00.000 NULL NULL 12005,00
4 2011-10-02 13:48:25.680 3 NULL NULL NULL 8000,00
5 2011-10-02 13:48:26.683 4 NULL NULL NULL 9000,00
6 2011-10-02 13:48:27.683 5 NULL CUST1002 NULL NULL
(6 row(s) affected)
Transaction 1 history
OperationType OperationDateTime AuditID ID Date CustomerID Type Amount
------------- ----------------------- ----------- ----------- ----------------------- -------------------------------------------------- ---- ---------------------
U 2011-10-02 13:56:41.420 1 1 NULL NULL NULL 12000,00
U 2011-10-02 13:56:43.430 3 1 2011-01-01 00:00:00.000 NULL NULL 12005,00
I 2011-10-02 13:56:40.363 0 1 2011-01-02 11:11:11.000 CUST1001 INV 12014,00
(3 row(s) affected)
如何解释这些结果? “ I”行包含实际值,而“ U”行包含旧值。
例:
Amount
字段,第一个值为12014,最后一个值为12014。 CustomerID
字段未修改。 [Date]
字段从2011-10-02 13:56:43.430
2011-01-01 00:00:00.000
修改为2011年1 2011-10-02 13:56:43.430
2011-01-02 11:11:11.000
。 我发现这个答案是正确的! 对表进行更新后,将使用UPDATE触发器来执行操作。
CREATE TRIGGER tr_Orders_UPDATE
ON Orders
AFTER UPDATE
AS
--Make sure Priority was changed
IF NOT UPDATE(Ord_Priority)
RETURN
--Determine if Priority was changed to high
IF EXISTS (SELECT *
FROM INSERTED a
JOIN DELETED b ON a.Ord_ID=b.Ord_ID
WHERE b.Ord_Priority <> 'High' AND
a.Ord_Priority = 'High')
BEGIN
DECLARE @Count tinyint
SET @Count = (SELECT COUNT(*)
FROM INSERTED a
JOIN DELETED b ON a.Ord_ID=b.Ord_ID
WHERE b.Ord_Priority <> 'High' AND
a.Ord_Priority = 'High')
PRINT CAST(@Count as varchar(3))+' row(s) where changed to a priority of High'
END
go
在第一部分中,INSERT触发器监视优先级为“高”的订单。 UPDATE触发器监视优先级从其他更改为“高”的订单。
IF语句检查以查看Ord_Priority值是否已更改。 如果没有,我们可以通过立即退出触发器来节省一些时间。
删除的表包含更新前的值,插入的表包含新值。 将表连接在一起后,很容易知道优先级何时从其他更改为“高”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.