2015-03-13 81 views
0

這是我的(進行中)觸發器。SQL問題觸發舊值和新值

ALTER TRIGGER [dbo].[trgInsertUpdate] 
ON [dbo].[joinreason] 
AFTER INSERT, UPDATE 
AS 
BEGIN 
    DECLARE @jr_active AS char(1), @jrid AS int; 
    SELECT @jr_active = (SELECT jr_active FROM INSERTED) 
    SELECT @jrid = (SELECT jrid FROM INSERTED) 

    IF UPDATE(jr_active) 
    BEGIN 
     IF (jr_active = 'N') 
     BEGIN 
      UPDATE joinreason 
      SET jr_active = 'N' where jr_par_jrid = jrid; 
     END 
    END 
END 

jr_active列是'Y'或'N'。 業務需求是:

當記錄沒有jr_par_id時,它被認爲是父項。

當記錄有jr_par_id時,它被認爲是孩子。

  1. ==父

當父母的jr_active列從 'Y' 改爲 'N' 的jrid孩子的jr_par_id:

  1. 所有的孩子都應該更新在jr_active列中爲'N'

我無法理解如何引用舊值(更新後更改的值)和新值(即將要更新的值)。

任何人都可以看到我要去哪裏錯了嗎?

使用SQL Server 2008

+1

請記住,觸發設置爲基礎的:如果你想測試我的測試代碼可以在這裏找到

!當'joinreason'中更新多行時,您現在的代碼將無法正常運行。 – NickyvV 2015-03-13 14:26:27

+0

在給定的時間內不會更新一行。 – Curly5115 2015-03-13 14:27:49

+0

如果插入了多行,那麼觸發器將拋出錯誤。 – 2015-03-13 14:29:37

回答

2

觸發更新後,大火有機會獲得兩個虛擬表:的其中包含了舊版本(更新之前)inserted其中包含更改的行的新的更新版本,deleted改變了行。要讓觸發器檢測一行是否發生了變化,您需要連接兩個虛擬表並比較感興趣的值。

我相信這觸發是你想要什麼:

CREATE TRIGGER [dbo].[trgInsertUpdate] 
ON [dbo].[joinreason] 
AFTER INSERT, UPDATE 
AS 
BEGIN 
    IF UPDATE(jr_active) 
    BEGIN 
     UPDATE joinreason 
     SET jr_active = 'N' 
     FROM joinreason j 
     JOIN inserted i ON i.jrid = j.jr_par_jrid 
     JOIN deleted d ON i.jrid = d.jrid 
     WHERE d.jr_active = 'Y' AND i.jr_active = 'N' 
    END 
END 

inserted虛表的連接限制了更新,以兒童和加入與deleted篩選出有其jr_activeY變爲父行Nhttp://pastebin.com/GzVjX4dT

+1

非常感謝。您不僅提供了工作解決方案,而且還介紹了它的工作原理。真棒。 – Curly5115 2015-03-13 15:33:43