删除触发器作为“ON DELETE CASCADE”的替代避免“多重级联路径”?

发布于 2024-09-07 11:06:49 字数 1118 浏览 3 评论 0原文

下表定义:

   CREATE TABLE Customers( id INT NOT NULL PRIMARY KEY, name [varchar](50) )

    CREATE TABLE Orders ( id INT NOT NULL PRIMARY KEY, 
                          customer INT FOREIGN KEY 
                          REFERENCES Customers(id) ON DELETE CASCADE )

    CREATE TABLE OrderDetails ( id INT NOT NULL PRIMARY KEY, 
                                order INT FOREIGN KEY REFERENCES Orders(id) ON DELETE CASCADE, 
                                customer INT FOREIGN KEY REFERENCES Customers(id) ON DELETE CASCADE  )

在sql server中不可能,因为有多个级联路径。

OrderDetails,让我们看看在删除带有包含以下内容的触发器的订单时是否可以强制引用完整性:

DELETE FROM OrderDetails
    FROM Deleted d
    INNER JOIN OrderDetails od
    ON od.order = d.id

我想让我们在 order 列上创建没有 ON DELETE CASCADE的 在 Orders 中删除之后,所以这是不可能的(DELETE 语句与 REFERENCE 约束冲突)。

我认为问题在于模型设计,从 OrderDetails 到 Customers 的引用是一个糟糕的设计。然而,否则可以为属于不同客户的订单创建订单详细信息。

两个问题:

  • 最好的模型设计是什么?
  • 仍然可以使用触发器吗?

编辑:我删除了从 OrderDetails 到 Customers 的引用,它没有任何意义。 这解决了所有问题。

The following table definition:

   CREATE TABLE Customers( id INT NOT NULL PRIMARY KEY, name [varchar](50) )

    CREATE TABLE Orders ( id INT NOT NULL PRIMARY KEY, 
                          customer INT FOREIGN KEY 
                          REFERENCES Customers(id) ON DELETE CASCADE )

    CREATE TABLE OrderDetails ( id INT NOT NULL PRIMARY KEY, 
                                order INT FOREIGN KEY REFERENCES Orders(id) ON DELETE CASCADE, 
                                customer INT FOREIGN KEY REFERENCES Customers(id) ON DELETE CASCADE  )

isn't possible in sql server because there are multiple cascade paths.

I thought let's create OrderDetails without the ON DELETE CASCADE on column order and let's see whether it is possible to enforce referential integrity when deleting an order with a trigger containing:

DELETE FROM OrderDetails
    FROM Deleted d
    INNER JOIN OrderDetails od
    ON od.order = d.id

The trigger fires after the delete in Orders, so it is not possible (The DELETE statement conflicted with the REFERENCE constraint).

I believe the problem lies in the model design and the reference from OrderDetails to Customers is a bad design. However otherwise it would be possible to create OrderDetails for Orders that belong to different Customers.

Two questions:

  • what is the best model design?
  • is it nevertheless possible to use a trigger?

EDIT: I removed the reference from OrderDetails to Customers, it doesn't make any sense.
This resolves all issues.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晨曦慕雪 2024-09-14 11:06:50

我会通过根本不将 Customer 放入 OrderDetails 来避免这个问题,因为它可以从加入 Orders 中派生出来。

即使使用外键,也无法阻止 OrderDetails 中的 Customer 与 Orders 中的 Customer 不同。

另外,您真的想要对此进行级联删除吗?想必企业会需要一些历史订单记录。

I would avoid this issue by not putting Customer in OrderDetails at all, as it is derivable from joining on Orders.

As it stands even with the Foreign Key there is nothing preventing the Customer in OrderDetails being different from the one in Orders.

Additionally do you really want a cascading delete for this anyway? Presumably the business will want some record of historic orders.

你没皮卡萌 2024-09-14 11:06:50

当然,在 OrderDetails 中包含 CustomerId 是不正确且没有意义的。这会给你一种传递依赖。
此外 - 根据您的实际模型 - 如果有任何订单与其相关,则绝不允许删除客户。您应该计划一个布尔值,或者更好的日期字段,如 DeadCustomer :/

对于结构:
客户:ID、姓名等
订单:订单 ID、订单日期、客户 ID...
订单详细信息:订单 ID、产品 ID、数量、单价...
产品:产品 ID、描述、状态、单价...

For sure, it is not correct and does not make sense to have the CustomerId in the OrderDetails. This would give you a kind of transitive dependency.
Additionally - depending on your real model - one should never be allowed to delete a Customer if any Order relates to it. You should rather plan either a Boolean, or beter a Date field like DeadCustomer :/

For the structure:
Clients: Id, Name, etc
Order: OrderId, OrderDate, CustID...
OrderDetails: OrderId, ProductId, Quant, UnitPrice...
Products: ProductId, Description, Status, UnitPrice...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文