我正在尝试制作一个触发器,在更新表时记录2列(地址和邮政编码)的先前数据,包括更新的用户和时间戳。我还需要更新只有在两个列同时更新时才会发生,如果它们不是需要回滚的更改。我创建的表格:
CREATE TABLE PreviousAddress
(
a_user char (10) ,
a_date date ,
a_ID int IDENTITY (1, 1) NOT NULL ,
a_CustomerID int ,
a_PrevAddr char (50),
a_PrevPostCode char(10),
CONSTRAINT [PK_Previous] PRIMARY KEY(a_id))
我找不到任何关于如何制作将数据插入此表的触发器的文档,但只有在邮政编码和地址都被编辑的情况下?
我的尝试:
CREATE TRIGGER Addr_Audit
ON Customers
AFTER UPDATE
AS
IF UPDATE(Cus_Addr) OR UPDATE(Cus_Post_Code)
BEGIN
INSERT INTO PreviousAddress
SELECT CURRENT_USER, CURRENT_TIMESTAMP, CustomerID, CustomerAddress, CustomerPostcode FROM Deleted
END
答案 0 :(得分:2)
不使用UPDATE,而是连接已删除和已插入的表,这将处理多个更新,并仅插入已更改的更新。
CREATE TRIGGER Addr_Audit
ON Customers
AFTER UPDATE
AS
-- insert on PreviousAddres those records where
-- both, Cus_Addr and Cus_Post_Code has changed
--
INSERT INTO PreviousAddress
SELECT d.CURRENT_USER,
d.CURRENT_TIMESTAMP,
d.CustomerID,
d.CustomerAddress,
d.CustomerPostcode
FROM deleted d
INNER JOIN inserted i
ON d.CustomerID = i.CustomerID
WHERE i.Cus_Addr <> d.Cus_Addr
AND i.Cus_Post_Code <> d.Cus_Post_Code
-- Rollback changes on the other records.
--
UPDATE Customers
SET Cus_Addr = d.Cus_Addr,
Cus_Post_Code = d.Cus_Post_Code,
--
-- add other fields to rollback changes
--
FROM Customers c
INNER JOIN inserted i
ON i.CustomerID = c.CustomerID
INNER JOIN deleted d
ON d.CustomerID = c.CustomerID
WHERE i.Cus_Addr = d.Cus_Addr
OR i.Cus_Post_Code = d.Cus_Post_Code
为了问题,我将添加另一个解决方案。如果检测到至少一个记录,其中只有一个字段Cus_Addr或Cus_Post_Code已更改,则此回滚全部更改。
CREATE TRIGGER Addr_Audit
ON Customers
AFTER UPDATE
AS
-- check Cust_Addr and Cust_Post_Code, both has been changed
-- if not, rollback the whole transaction and raises one error
--
IF EXISTS (SELECT 1
FROM inserted i
INNER JOIN deleted d
ON i.CustomerID = d.CustomerID
WHERE (i.Cus_Addr <> d.Cus_Addr
AND
(i.Cus_Post_Code = d.Cus_Post_Code)
OR (i.Cus_Addr = d.Cus_Addr
AND
(i.Cus_Post_Code <> d.Cus_Post_Code)
)
BEGIN
ROLLBACK TRANS;
RAISERROR('ERROR: Must change P.C. and address',16,1);
END
-- insert on PreviousAddres those records where
-- both, Cus_Addr and Cus_Post_Code has changed
--
INSERT INTO PreviousAddress
SELECT d.CURRENT_USER,
d.CURRENT_TIMESTAMP,
d.CustomerID,
d.CustomerAddress,
d.CustomerPostcode
FROM deleted d
INNER JOIN inserted i
ON d.CustomerID = i.CustomerID
WHERE i.Cus_Addr <> d.Cus_Addr
AND i.Cus_Post_Code <> d.Cus_Post_Code