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 サーバーでは使用できません。

ON DELETE CASCADEon 列を指定せずに OrderDetails を作成orderして、以下を含むトリガーで注文を削除するときに参照整合性を強制できるかどうかを見てみましょう。

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

Orders での削除の後にトリガーが起動するため、実行できません (DELETE ステートメントが REFERENCE 制約と競合しました)。

問題はモデルの設計にあり、OrderDetails から Customers への参照は設計が悪いと思います。ただし、それ以外の場合は、異なる顧客に属する注文の OrderDetails を作成することができます。

2 つの質問:

  • 最適なモデル設計は?
  • それにもかかわらず、トリガーを使用することは可能ですか?

編集: OrderDetails から Customers への参照を削除しましたが、意味がありません。これにより、すべての問題が解決されます。

4

2 に答える 2

1

Ordersに参加することで派生できるため、CustomerをOrderDetailsにまったく入れないことで、この問題を回避します。

外部キーを使用しても、OrderDetailsの顧客がOrdersの顧客と異なることを妨げるものは何もありません。

さらに、とにかくこれをカスケード削除したいですか?おそらく、企業は過去の注文の記録を必要とするでしょう。

于 2010-06-28T10:41:49.743 に答える
1

確かに、OrderDetails に CustomerId を含めることは正しくなく、意味がありません。これにより、一種の推移的な依存関係が得られます。
さらに、実際のモデルによっては、顧客に関連する注文がある場合、その顧客を削除することは許可されるべきではありません。ブール値を計画するか、DeadCustomer のような日付フィールドを計画する必要があります:/

構造の場合:
クライアント: ID、名前など
注文: OrderId、OrderDate、CustID...
OrderDetails: OrderId、ProductId、Quant、UnitPrice...
製品: ProductId、Description、Status、UnitPrice...

于 2010-06-28T10:47:18.983 に答える