【问题标题】:Cascade Delete Query级联删除查询
【发布时间】:2011-04-04 18:00:49
【问题描述】:

我有三张桌子。 产品、公司、员工

Product 表的ProductId 是Company 的foregin key Company 表的 CompanyId 是 Employee 的外键

所以在从 Product 表中删除 ProductId 时,其他表中的所有相关记录都应该删除。但我不能触及模式(不能使用改变表)。在这种情况下我应该如何编写查询..

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    如果您无法添加传播删除的约束,则必须自己编写所有必要的删除:

    delete employee where companyid in (select companyid from company c where productid = xxx);
    delete company where productid=xxx;
    delete product where productid=xxx;
    

    【讨论】:

    • 那么我需要写3个查询,不能一个完成吗?
    • 不。但是你可以围绕这 3 个查询编写一个存储过程。
    • 我认为这是有充分理由的。如果您想要级联删除,请使用“ON DELETE CASCADE”选项进行引用约束。但在某些情况下,您根本不希望这样做,因为删除方式超出预期的危险很大。例如,您绝对不想仅仅因为有人试图删除已售出的产品而删除发票项目。如果 DELETE 语句有一个“CASCADE”选项,人们会在不知道它们造成多少损害的情况下使用它。
    • 我看到的缺点是,在上面的查询 1 运行时,没有任何东西禁止其他用户添加员工,导致查询 2 因违反外键约束而崩溃。使用带有级联删除的外键,这不会成为问题,尽管删除会话将挂起,直到另一个会话提交或回滚。您应该做的是同时使用 ON DELETE CASCADE 并使用上面的 SQL。 (Delete Cascade 是出了名的慢。)
    • 要使 ON DELETE CASCADE 运行得相当快,您需要在外键列上建立索引。即使没有 ON DELETE CASCADE 子句,这对于外键约束也是一种很好的做法。
    【解决方案2】:

    试试这个选项。我没有环境来测试这个。我想通过一些更改它应该在你的最后工作。

    DELETE Product,Company,Employee 
    FROM 
    user LEFT JOIN items ON product.productid = company.productid 
    LEFT JOIN orders ON company.productid = product.productid 
    WHERE product.productid = [$productid]
    

    【讨论】:

    • 您不能将连接放在删除语句中
    猜你喜欢
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多