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 中是不可能的,因为有多个级联路径。

我想让我们创建没有ON DELETE CASCADEon 列的 OrderDetails order,让我们看看在删除带有触发器的订单时是否可以强制引用完整性:

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

触发器在 Orders 中删除后触发,因此不可能(DELETE 语句与 REFERENCE 约束冲突)。

我认为问题出在模型设计上,从 OrderDetails 到客户的参考是一个糟糕的设计。但是,否则可以为属于不同客户的订单创建 OrderDetails。

两个问题:

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

编辑:我从 OrderDetails 中删除了对客户的引用,这没有任何意义。这解决了所有问题。

4

2 回答 2

1

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

即使使用外键,也没有什么可以阻止 OrderDetails 中的客户与 Orders 中的客户不同。

此外,您真的想要级联删除吗?据推测,企业需要一些历史订单记录。

于 2010-06-28T10:41:49.743 回答
1

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

对于结构:
客户:ID、名称等
订单:OrderId、OrderDate、CustID...
OrderDetails:OrderId、ProductId、Quant、UnitPrice...
产品:ProductId、描述、状态、UnitPrice...

于 2010-06-28T10:47:18.983 回答