2012-04-03 162 views
19

我想創建一個基本的數據庫觸發器,當從database2.table2中刪除一行時,有條件地刪除database1.table1中的行。我是觸發器的新手,希望能夠學習完成這一任務的最佳方式。這是我迄今爲止所擁有的。建議?SQL Server ON刪除觸發器

CREATE TRIGGER sampleTrigger 
    ON database1.dbo.table1 
    FOR DELETE 
AS 
    IF EXISTS (SELECT foo 
       FROM database2.dbo.table2 
       WHERE id = deleted.id 
       AND bar = 4) 

-- If there is a row that exists in database2.dbo.table2 
-- matching the id of the deleted row and bar=4, delete 
-- it as well. 

-- DELETE STATEMENT? 

GO 
+4

您需要考慮到觸發器被觸發**每個語句**一次(並且** NOT **一次pe r行與許多開發人員相信),並且'Deleted'僞表可能包含**多行**(如果您的語句刪除多行) – 2012-04-03 15:41:40

+0

@marc_s - 在系統中,一次只能刪除一行(應用程序前端)。你能詳細說明你的意思嗎?是否像將WHERE id = deleted.id'更改爲'WHERE id IN(SELECT id FROM FROM)'那樣簡單? – 2012-04-03 15:52:39

+2

@ShawnH。是的,它應該是那麼簡單。我認爲馬克意味着如果從某處觸發大規模刪除,觸發器只會針對整個語句而不是每行觸發一次,因此使用「IN」應該對其進行排序。 – Bridge 2012-04-03 15:59:35

回答

49
CREATE TRIGGER sampleTrigger 
    ON database1.dbo.table1 
    FOR DELETE 
AS 
    DELETE FROM database2.dbo.table2 
    WHERE bar = 4 AND ID IN(SELECT deleted.id FROM deleted) 
GO 
+0

謝謝。這很簡單,並且像魅力一樣工作。 – 2012-04-03 16:23:10

2

INSERTEDDELETED是虛擬表。他們需要在FROM條款中使用。

CREATE TRIGGER sampleTrigger 
    ON database1.dbo.table1 
    FOR DELETE 
AS 
    IF EXISTS (SELECT foo 
       FROM database2.dbo.table2 
       WHERE id IN (SELECT deleted.id FROM deleted) 
       AND bar = 4) 
8

最好使用:

DELETE tbl FROM tbl INNER JOIN deleted ON tbl.key=deleted.key 
1

我會建議使用exists代替in因爲在某些情況下這意味着空值the behavior is different,所以

CREATE TRIGGER sampleTrigger 
    ON database1.dbo.table1 
    FOR DELETE 
AS 
    DELETE FROM database2.dbo.table2 childTable 
    WHERE bar = 4 AND exists (SELECT id FROM deleted where deleted.id = childTable.id) 
GO