CASCADEを競合すると外部キーの要件をRESTRICT?
-
20-08-2019 - |
質問
私は、プロジェクト内のファイルと依存関係を追跡するデータベースに取り組んでいます。簡単に言うと、私は、主に2つのテーブルを持っています。 PROJECTSテーブルのリストが名前やその他のプロパティを投影し、FILESテーブルには、ファイルの一覧が表示されます。私は、データベースからプロジェクトのレコードを削除するので、もし、CASCADEに設定し、外部キーとしてプロジェクトにすべてのファイルのエントリポイントは、すべてのファイルレコードも同様に消えます。これまでのところ、とてもいいます。
今、私は追加の依存関係のテーブルを持っています。依存関係テーブルの各レコードは、最初のファイルが第二に依存していることを指定して、二つのファイルです。再び、これらの外部キーは、最初はCASCADE(私は、ファイルのエントリを削除した場合ので、このレコードが削除される)に設定されている、しているが、2番目は(制限するために設定されているので、私は他のファイルが依存している場合、ファイルのエントリを削除することは許されないのですその上)。ここでも、すべてが良いようです。
残念ながら、私はもはや単一のSQL DELETEステートメントでプロジェクトを削除することはできませんね!カスケード削除するファイルを削除しようとしますが、これらのいずれかの依存関係テーブルに表示された場合、RESTRICT外部キーは、(他の列は、CASCADEであるため、依存関係テーブルのそのレコードが削除されるにもかかわらず)、削除を防止します。私が持っている唯一の回避策は、依存関係レコードの制約のどれが侵害されていないので、ファイルを削除する正確な順序を計算し、プロジェクトを削除しようとする前に、一度にファイルレコード1を削除することです。
単一のSQLが正しく、他の削除をカスケード接続しますプロジェクトテーブルから削除するように、私のデータベーススキーマを設定する方法はありますか?私はFirebirdの2.1を使用していますが、それはすべての違いを、私は知らない - ?それはこの作品を作るための方法があるようにあるべきように思える。
解決
あなたはカスケード外部キーによる削除の順序を制御することはできませんが、このプロジェクトに属し、また、<=に記載されていPROJECTS
内の行を削除するFILES
にトリガーを設計することができるかもしれません>その他のDEPENDENCIES
に依存として。それBEFORE DELETE
トリガー作るので、カスケード効果の前に実行する必要があります。
このような何かます:
CREATE TRIGGER Del_Child_Files FOR PROJECTS
BEFORE INSERT
AS BEGIN
FOR SELECT F.FILE_ID FROM FILES F JOIN DEPENDENCIES D
ON F.FILE_ID = D.CHILD_ID
WHERE F.PROJECT_ID = OLD.PROJECT_ID
INTO :file_id
DO
DELETE FROM FILES WHERE FILE_ID = :file_id;
DONE
END
プロジェクトを削除すると、ですから、これはそう残りのすべてのファイルは、依存関係のない<=>内の行を削除するには、他のすべてのファイルに依存しているプロジェクトの「子」ファイル、およびこのカスケードを削除します。プロジェクトのあなたの削除は今、これらのファイルを削除するようにカスケードすることができます。
私はこれをテストしていないと、私のFirebirdの構文は錆びたかもしれないが、おそらくそれはあなたが始められるでしょう。
もちろん、あなたのデータではなく、生のデータのコピーでこれをテストしてください!
他のヒント
制約のチェックがコミット・ポイントまで延期することができるシステムサポート延期制約を、していますか?
たぶんそれはしかしOracleだけのことです。