2012-04-03 123 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