2011-09-23 43 views
4

后,我有一个简单的细节表所示:插入,更新时间戳触发两列主键

listid 
custid 
status 
last_changed 

主键由两个listidcustid的。

现在我试图设置一个触发器,在每次插入或更新发生时将last_changed列设置为当前日期时间。我发现很多关于如何使用单个PK列的信息,但是对于多个PK,如何正确指定INSERTED表中的PK会产生混淆。

触发器必须在SQL Server 2005/2008/R2中运行。

感谢您的工作触发代码!

奖金也将检查数据是否实际上被更改,并且只在该情况下更新last_changed,但为了实际理解如何正确编码主要问题,我希望将其看作单独的代码块if在所有。

回答

8

嗯....只是因为主键是由两列的真的不应该有很大的不同....

CREATE TRIGGER dbo.trgAfterUpdate ON dbo.YourTable 
AFTER INSERT, UPDATE 
AS 
    UPDATE dbo.YourTable 
    SET last_changed = GETDATE() 
    FROM Inserted i 
    WHERE dbo.YourTable.listid = i.listid AND dbo.YourTable.custid = i.custid 

你只需要建立两个表之间的连接(你自己的数据表和Inserted伪表)在两列...

我是否错过了什么? .....

+0

这将工作多行?所有的触发器示例都会显示代码,如“SELECT [id] FROM INSERTED”中的WHERE [id]),并且使用IN将无法正确工作两个PK。 – Tom

+0

@Tom:** YES当然!**这只是简单地将您的表格连接到两个PK列上的'Inserted'表格 - 没有限制操作会影响触发器触发的行数 –

+0

ok,请尝试那现在。顺便说一句:你有错误的订单FROM和SET行... – Tom

0

你可以像下面比较来自inserted和deleted表中的数据检查每个字段触发:

CREATE TRIGGER [dbo].[tr_test] ON [dbo].[table] 
    AFTER INSERT, UPDATE 
    AS 
    BEGIN 
    DECLARE @old_listid INT 
    DECLARE @old_custid INT 
    DECLARE @old_status INT 

    DECLARE @new_listid INT 
    DECLARE @new_custid INT 
    DECLARE @new_status INT 

    SELECT @old_listid=[listid], @old_custid=[custid], @old_status = [status] FROM [deleted] 

    SELECT @new_listid=[listid], @new_custid=[custid], @new_status = [status] FROM [inserted] 

    IF @oldstatus <> @new_status 
    BEGIN 
     UPDATE TABLE table SET last_changed = GETDATE() WHERE [listid] = @new_listid AND [custid] = @new_custid 
    END 

END 
+1

这将**不工作**,因为'Inserted'和'Deleted'可能包含**多行**(当批处理语句执行完毕)并且你的'SELECT'将失败(或随机选择一个条目.....)。 SQL Server触发器每行都执行** NOT ** - 每批执行** **(可能影响多行) –

+0

@marc_s:我认为对于批量更新,您的答案是正确的。感谢您的指导。 –

1
CREATE TRIGGER dbo.trgAfterUpdate ON dbo.YourTable 
    AFTER INSERT, UPDATE 
    AS 
     UPDATE dbo.YourTable 
     SET last_changed = GETDATE() 
     FROM Inserted i 
     JOIN dbo.YourTable.listid = i.listid AND dbo.YourTable.custid = i.custid 
    WHERE NOT EXISTS 
(SELECT 1 FROM Deleted D Where D.listid=I.listid AND D.custid=i.custid AND (D.status=i.status) 

在这里,我假设stasus列不能为空。如果是的话,你应该添加额外的代码来检查是否有一列是NULL

+0

你还记得为什么你添加了“WHERE NOT EXISTS(SELECT ...”部分吗?我知道6年过去了,但我希望你能花时间去帮助。 –