是否可以在一个SQL语句中删除主和详细记录?

时间:2009-09-02 16:01:10

标签: sql

未在此特定数据库上设置级联删除。只是想知道是否有办法在一次滑动中执行它比运行两个单独的声明更有效。

5 个答案:

答案 0 :(得分:4)

没有。

您可以对一个命令执行两个语句:

从ChildTable中删除;从ParentTable中删除;

但实际上这是两个陈述。

您可以在ChildTable上设置删除父记录的触发器。

既不符合您的标准。

答案 1 :(得分:1)

应该在交易中 - 它可能效率较低,但数据完整性要好得多

BEGIN TRAN
DELETE FROM ChildTable WHERE safetycatch=0
DELETE FROM ParentTable WHERE safetycatch=0
COMMIT TRAN

编辑 - 如果你真的只想使用一个语句,那么就可以创建一个存储过程,例如

CREATE PROCEDURE DeleteBoth AS
    BEGIN TRAN
    DELETE FROM ChildTable WHERE safetycatch=0
    DELETE FROM ParentTable WHERE safetycatch=0
    --ERROR HANDLING IF STUFF GOES WRONG THEN ROLLBACK TRAN
    COMMIT TRAN
GO

然后你可以用

在一行中运行它
EXEC DeleteBoth

使用缓存的执行计划,我认为与级联删除相比,性能差异可以忽略不计,因为这几乎就是幕后发生的事情。

答案 2 :(得分:1)

是,但仅当您定义外键关系并使用ON DELETE CASCADE选项时。

其他所有内容都需要两个语句,即使语句恰好在同一个事务中。

答案 3 :(得分:0)

正如日产范提到的那样,触发器会做到这一点。正如wefwfwefwe建议的那样,如果必须全有或全无,请使用交易。

根据您的绝望程度,您可以通过过于复杂的方式将两者结合使用发布到数据库的单个语句:

  1. 在表的连接上构建视图。
  2. 在其上添加一个INSTEAD OF触发器,编码为从两个表中删除相应的行。不是真的推荐,但你可以做到。

答案 4 :(得分:0)

通常,没有设置级联删除(通常与阻塞和锁定有关)是有充分理由的。由于它们未设置,因此您需要自己为所有子表和父表编写单独的delete语句。我建议最好的方法是在使用事务的存储过程中,因为如果你关心数据的完整性,你不想做部分删除。确保有错误捕获和回滚。