2

プロジェクト内のファイルと依存関係を追跡するデータベースに取り組んでいます。簡単に言えば、2 つのメイン テーブルがあります。PROJECTS テーブルにはプロジェクト名とその他のプロパティがリストされ、FILES テーブルにはファイルがリストされます。すべてのファイル エントリは、CASCADE に設定された外部キーとしてプロジェクトを指しているため、データベースからプロジェクト レコードを削除すると、すべてのファイル レコードも消えてしまいます。ここまでは順調ですね。

これで、追加の DEPENDENCIES テーブルができました。依存関係テーブルの各レコードは 2 つのファイルであり、最初のファイルが 2 番目のファイルに依存することを指定します。繰り返しますが、これらは外部キーです。最初のキーは CASCADE に設定されています (つまり、ファイル エントリを削除すると、このレコードは削除されます)。2 番目のキーは RESTRICT に設定されています (したがって、他のファイルが依存している場合、ファイル エントリを削除することはできません)。その上で)。繰り返しますが、すべてが良さそうです。

残念ながら、単一の SQL delete ステートメントでプロジェクトを削除することはできなくなったようです! 削除はファイルのカスケード削除を試みますが、これらのいずれかが DEPENDENCIES テーブルに表示される場合、RESTRICT 外部キーによって削除が妨げられます (他の列が CASCADE であるため、依存関係テーブルのそのレコードは削除されますが)。私が持っている唯一の回避策は、ファイルを削除する正確な順序を計算して、依存関係レコードの制約に違反しないようにし、プロジェクトを削除する前に一度に 1 つずつファイル レコードを削除することです。

プロジェクト テーブルからの単一の SQL 削除が他の削除を正しくカスケードするように、データベース スキーマを設定する方法はありますか? 私は Firebird 2.1 を使用していますが、それが違いを生むかどうかはわかりません。これを機能させる方法があるはずです。

4

2 に答える 2

4

カスケード外部キーを使用して削除の順序を制御することはできませんが、このプロジェクトに属し、他の に依存するものとしてリストされている のPROJECTS行を削除するトリガーを設計できる場合があります。これをトリガーにして、カスケード効果の前に実行する必要があります。FILESDEPENDENCIESFILESBEFORE 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

したがって、プロジェクトを削除すると、他のファイルに依存するプロジェクトのすべての「子」ファイルが削除され、これがカスケードして行を削除するDEPENDENCIESため、残りのすべてのファイルは依存関係から解放されます。プロジェクトを削除すると、カスケードしてこれらのファイルを削除できるようになりました。

私はこれをテストしておらず、私の Firebird 構文はさびているかもしれませんが、おそらくそれで始められるでしょう。

明らかに、ライブデータではなく、データのコピーでこれをテストしてください!

于 2008-12-09T19:24:31.383 に答える
0

システムは、コミット ポイントまで制約チェックを延期できる遅延制約をサポートしていますか?

多分それはただのオラクルのことです。

于 2008-12-09T19:11:08.587 に答える