2015-10-16 83 views
0

复杂得多然后这一点,但是这是基本的SQL服务器:删除行,如果没有约束错误

  • Person表(ID,姓名,EMAILADDRESS)
  • Salesperson表(ID,PERSONID)
  • CustomerServiceRep表(ID,PERSONID)

杰夫是营业员(ID = 4)和customerservicerep(ID = 5)PERSONID = 1。

简单

Trigger on SalesPerson Table 
AFTER DELETE 
AS 
    DECLARE @personID int = (SELECT personID FROM deleted); 

    IF @personID IS NOT NULL 
    BEGIN TRY 
     DELETE FROM Person 
     WHERE Person.id = @personID; 
    END TRY 
    BEGIN CATCH 
    END CATCH 

DELETE FROM SalesPerson WHERE id=4; 

原因

消息3616,级别16,状态1
触发执行过程中出现错误而引发。该批次已被中止,并且用户事务(如果有的话)已被回滚。

我敢肯定,如果它存在某种约束,有一种更简单的方法可以不删除personID。或者赶上约束。在可能使用相同表/约束(外键)的表/列更多时,查看可能存在的每个可能的表似乎是非常重复的并且可能更困难。

回答

0

您需要一个而不是删除触发器,而不是一个后触发器。

CREATE Trigger tr_Delete_person 
on Person 
INSTEAD OF DELETE 
AS 
BEGIN 
    SET NOCOUNT ON; 

-- Delete any child records 

    Delete FROM SalesPerson 
    WHERE EXISTS (SELECT 1 FROM deleted 
        WHERE personID = SalesPerson.personID) 


    Delete FROM CustomerServiceRep 
    WHERE EXISTS (SELECT 1 FROM deleted 
        WHERE personID = CustomerServiceRep .personID) 


-- Finally delete from the person table 
    DELETE FROM Person 
    WHERE EXISTS (SELECT 1 FROM deleted 
        WHERE personID = Person .personID) 


END 
+0

似乎它会摆脱与“杰夫”相关的一切。只想删除销售人员“jeff”,而不是customerservicerep“jeff”,如果“jeff”人仍然存在,因为“jeff”也是customerservicerep,则不要删除人员。我觉得应该有一个完整的更简单的方法来做到这一点,而不添加每个表可能有personID来检查它是否存在之前删除人“杰夫” – user2828970

+0

@ user2828970,我会设置一个外键'人'和'SalesPerson'级联删除。'Person'和'CustomerServiceRep'之间没有级联的外键。如果有更多的引用'Person'的表,你需要为它们设置适当的级联动作的外键。 –

+0

我明白这可以如何有用。 Cascade对我来说是一件新事物。虽然看,但我还没有看到如何使它不删除人,如果它存在于不同的表中。 SalesPerson和CustomerServiceRep表基本相等(不优先于每个表)。可以从customerServiceRep中移除“jeff”,就像从SalesPerson中移除一样,但如果仍然存在某个地方,则不应删除该人员。显然,用长的代码行可以检查。 – user2828970

0

你还必须在你的触发一个根本缺陷,你似乎期望触发器将被解雇行一次 - 这是在SQL Server的情况。相反,触发器在每个语句处触发一次,并且伪表Deleted可能包含多行

鉴于该表可能包含多行 - 您期望在此处选择哪一个?

DECLARE @personID int = (SELECT personID FROM deleted); 

它是不确定的 - 你会从一个获取的价值,任意行Deleted和所有其他被忽略 - 通常你想要的!

您需要用知识Deleted包含多行重写您的整个触发器!您需要使用基于集合的操作 - 不要指望Deleted中只有一行!