2012-04-02 170 views
2

更新的行我有一個問題,我的更新觸發SQL - 刪除更新觸發

ALTER TRIGGER tr_MyTable 
ON MyTable 
AFTER UPDATE 
AS 

BEGIN TRAN 
SET NOCOUNT ON; 

     If Update(column) 
     Begin 
      DELETE FROM MyTable WHERE <condition> 
     End 


     SET NOCOUNT OFF 
COMMIT TRAN 
GO 

我試圖刪除行(從MayTable),目前已在updatete的MyTable。但是當我運行觸發器時該行不會被刪除。是否無法刪除當前在更新觸發器內更新的行? (刪除和更新在同一張桌子上)

謝謝!

編輯:

ALTER TRIGGER tr_MyTable 
ON MyTable 
AFTER UPDATE 
AS 

BEGIN TRAN 
SET NOCOUNT ON; 

     SELECT @ID = ID 
     FROM inserted 

     If Update(column) 
     Begin 
      DELETE FROM MyTable WHERE ID = @ID 
     End 


     SET NOCOUNT OFF 
COMMIT TRAN 
GO 

編輯2:

ALTER PROCEDURE sp_Update 
(
@ID INTEGER,) 
AS 

SET NOCOUNT ON 
Begin Tran 

      Update MyTable SET Column = Data where ID = @ID 

     Commit Tran 
SET NOCOUNT OFF 
GO 

此更新prosedure工作和列被更新。觸發器也被觸發,並且行刪除(print語句)被執行,但不是刪除語句。 但是,當我直接在表中更新列時,沒有形成觸發器,觸發器觸發,刪除語句正常工作。我不使用回滾。

+0

您已經在SQl服務器上做出了最糟糕的觸發錯誤,該錯誤是假設只有一條記錄將被插入或刪除表。如果你進行批量插入,這將不起作用。此代碼是錯誤的,必須更改。 – HLGEM 2012-04-02 21:28:00

+0

此外,您應該不要使用sp_開始存儲過程,因爲這是系統過程使用的過程。你也不應該寫一個沒有try-catch塊的事務,這樣它可以被回滾。 – HLGEM 2012-04-02 21:29:25

回答

2

你要怎麼刪除?

你應該閱讀你的價值從您的inserted和deleted表,如:

DELETE FROM MyTable WHERE id in (select ID from INSERTED) 
2

也許你想這樣做,在INSTEAD OF觸發器。如果有人試圖更新該列,則可以刪除該行,否則重新執行更新。這裏唯一的挑戰是你必須在觸發器內重新編寫更新語句。 (你也並不需要額外的BEGIN TRAN/COMMIT TRAN觸發內。)

CREATE TRIGGER dbo.tr2_myTable 
ON dbo.MyTable 
INSTEAD OF UPDATE 
AS 
BEGIN 
    SET NOCOUNT ON; 

    -- update the rows where the column hasn't changed 
    UPDATE s 
    SET col1 = i.col1, col2 = i.col2, ... 
    FROM dbo.MyTable AS s 
    INNER JOIN inserted AS i 
    ON s.key = i.key 
    INNER JOIN deleted AS d 
    ON i.key = d.key 
    AND i.column_that_should_not_change = d.column_that_should_not_change; 

    -- delete the rows where the column HAS changed 
    -- (note that this requirement sounds odd to me) 
    DELETE s 
    FROM dbo.MyTable AS s 
    INNER JOIN inserted AS i 
    ON s.key = i.key 
    INNER JOIN deleted AS d 
    ON i.key = d.key 
    AND i.column_that_should_not_change <> d.column_that_should_not_change; 
END 
GO 

注意,與您IF UPDATE()邏輯,這會觸發實際處理多行(例如,一些地方該列已經改變,有些地方沒有)。請注意,即使有人說UPDATE foo SET x = x;IF UPDATE(x)也是如此。

這假定您有一個關鍵列,並且column_that_should_not_change不可爲空。如果該列允許NULL,那麼邏輯會變得更復雜一些。

1

這是可能的。

如果你想,你可以在你的觸發器中有DELETE FROM MyTable,這應該工作。您是否測試過確認觸發器正在執行並且您的代碼到達DELETE FROM MyTable WHERE <condition>行?

+0

是的,觸發器正在執行,並且在從MyTable刪除行之前,其中行被執行,所以刪除行也應該執行。如Diego所述,我從插入的表中選擇我的。 – Liss 2012-04-02 17:12:57

+0

然後我認爲它一定是總是錯誤的。你爲什麼不向我們展示完整的DELETE行代碼? – daniloquio 2012-04-02 17:16:04

+0

我已更新我的原始帖子。 – Liss 2012-04-02 18:07:13