2017-08-08 5 views
0

2つのテーブル間のマスター - ディテールの関係がわかります(例:OrderHeadersOrderDetails)。マスターレコードが削除されると同時に詳細レコードを削除できるようにするには、2つのレコードのカスケード関係の削除アクションを設定できます。SQL Server:列の値が特定の値と等しい場合、レコードが削除されないようにするには

テーブルは本質的にデータベース内の他のものとは無関係です。しかし、ある時点で注文を請求書に変えれば、注文や関連する詳細を削除したくないということは明らかです。

私のOrderHeadersテーブルに相当する私は、注文が請求書に変換された場合にtrueに設定された単純なブール型列(Posted)を追加しました。

Postedの値がtrueの場合、レコードの削除を防ぐために、OrderHeadersテーブルにルールを適用するSQLの正しい方法は何ですか?

実際にこの特定の状況に対してより良いアプローチがある場合は、私は提案に完全に気付いています。新しいことを学ぶのは常に良いことです。

感謝

ドム

+0

私は右のそれを理解していれば、あなたは削除したいですOrderHeadersに削除がある場合の詳細から、別のテーブルにある投稿フラグに基づいて条件付きである必要がありますか? – Sujith

+0

注文書が請求書に変換されるときに何か他のものが保存されていますか?もしそうなら、それはPostedカラムの代わりにOrderHeadersにFKを持たず、そのFKをカスケードしないでください。 –

+0

@Sujith Postedフィールドは、OrderHeadersテーブル自体にあります。 –

答えて

0

何の条件CASCADEはありません。条件付き削除を処理するには、子行を手動で削除するトリガーを定義するだけです。 (SQL Server using triggers and geting rid of ON DELETE CASCADEを参照してください)

+0

私はそれが事実かもしれないことをむしろ恐れていました。個人的には、私はカスケード削除を嫌います。後で後悔することはあまりにも簡単です。したがって、この場合は、投稿された値に基づいてUIのレコードをフィルタリングし、それに応じて削除ボタンを有効または無効にすることをお勧めします。 –

0

どのように請求書を作成していますか?たとえば、SAPは注文ヘッダとその詳細を請求書と請求書の詳細にコピーするだけで、注文に必要なものはすべて実行できますが、請求書は同じままです。個人的には、基本的に同じデータを2回保存しているので、それは良い解決策ではないと思います(実際には、私が正しく覚えていれば、それは最も悪いです - データは2、3、4、 。

非常に簡単な解決策の1つは、カスケード削除ではない外部キーを使用して請求書を注文詳細テーブルに追加することです。この方法では、請求書を作成するときに、オーダーの詳細にリンクします。注文明細テーブルからレコードを削除できないと、親レコードはordersテーブルから削除できません。私は私が何を意味するかをお見せするためにrextester上の簡単なデモを行った

- ここでは完全な例である(ケースrextesterには使用できません):

CREATE TABLE OrderHeader 
(
    id int identity(1,1) primary key, 
    createDate datetime 
); 

CREATE TABLE Invoice 
(
    id int identity(1,1) primary key, 
    createDate datetime, 
    OrderId int foreign key references OrderHeader(id) 
); 

CREATE TABLE OrderDetails 
(
    id int identity(1,1) primary key, 
    orderId int foreign key references OrderHeader(id) on delete cascade, 
    itemId int, 
    invoiceId int NULL foreign key references Invoice(id) 
); 


INSERT INTO OrderHeader (createDate) VALUES (DATEADD(DAY, -1, GETDATE())), (GETDATE()); 

INSERT INTO OrderDetails (orderId, itemId) VALUES (1, 1), (2, 2); 

BEGIN TRANSACTION 

INSERT INTO Invoice (createDate, OrderId) VALUES (GETDATE(), 1) ; 

UPDATE OrderDetails 
SET invoiceId = scope_identity() 
WHERE OrderId = 1; 

COMMIT TRANSACTION 

SELECT 'Headers', * FROM OrderHeader; 
SELECT 'Details', * FROM OrderDetails; 
SELECT 'Invoice', * FROM Invoice; 

DELETE FROM OrderHeader WHERE Id = 2; 

SELECT 'Headers', * FROM OrderHeader; 
SELECT 'Details', * FROM OrderDetails; 
SELECT 'Invoice', * FROM Invoice; 

DELETE FROM OrderHeader WHERE Id = 1; 
関連する問題