【问题标题】:SQL Server trigger: Delete From Table AFTER DELETESQL Server 触发器:删除后从表中删除
【发布时间】:2020-09-30 00:51:18
【问题描述】:

我有一个像这样的名为announcement 的父表

create table announcement 
(
    aid int primary key, 
    name varchar,
    ......
)

还有另一个表 cars 继承自 announcement (tpt),如下所示

create table cars
(
     aid int primary key 
             foreign key references announcement(aid) on delete cascade,
     .....
) 

我知道如果我从announcement 中删除一行,那条记录也会从cars 中删除,因为“on delete cascade”。

但我想确定,如果从 cars 中删除了任何内容,那么该行也会从 announcement 中删除。

我写了一个触发器,而不是我从这个question 中学到的:

create trigger delCarFromA 
on car
after delete 
as
begin 
    delete from announcement 
    where announc.aid = car.aid;
end;

但我收到此错误:

无法绑定多部分标识符“car.aID”。

我该怎么办?

【问题讨论】:

  • 级联是一种方式,“向上”键,而不是向下;因为他们删除了该行作为外键出现在其他地方的行。删除 primary 表中的一行,因为将其作为外键删除的行将是一个糟糕的主意,因为这最终会删除远远超过您期望的 2 行(如 @987654332主键上的@ 将再次CASCADE)。
  • 删除触发器有一个反映删除记录的特殊表'deleted'。因此,不要使用 car.aid,而是使用 deleted.aid

标签: sql sql-server database triggers


【解决方案1】:

您的表格是 1:n 相关的。一个announcement 可以有很多辆汽车,一辆汽车可以有一辆announcement。如果您删除announcement,您将逐级删除所有汽车。但另一个方向需要一个规则,例如

  1. 如果一个 car 被删除,则其 announcement 及其所有其他汽车必须被删除。

  1. 如果announcement 的最后一个car 被删除(即announcement 没有汽车),则必须删除announcement

我假设你想要第二条规则。理想情况下,您的触发器将是语句后触发器,但 SQL Server 不支持这一点。与 SQL 标准中定义的不同,SQL Server 中的每个触发器都是隐式的FOR EACH ROW 触发器。

FOR EACH ROW 触发器中,您可以访问已删除的车行。但这不是通过car.aid 完成的,而是通过SQL Server 中的(select aid from deleted) 完成的。

如果你想应用第二条规则,我假设你还需要一个EXISTS 子句来查看announcement 是否还有汽车。

create trigger delCarFromA on car
after delete
as
begin 
  delete from announcement a
  where aid = (select aid from deleted)
  and not exists
  (
    select null
    from car c
    where c.aid = a.aid
  );
end;

如果您想删除announcemmnt,即使它还有汽车,请从触发器中删除EXISTS 子句。

【讨论】:

    【解决方案2】:

    请尝试以下代码,

    CREATE TRIGGER delCarFromA on cars
        FOR DELETE
    AS
        DELETE FROM dbo.announc
        WHERE aid IN(SELECT deleted.aid FROM deleted)
    GO
    

    祝你工作顺利!

    【讨论】:

      猜你喜欢
      • 2012-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多