2012-02-04 4 views
0

外部キーの依存関係が存在しないテーブルから行を削除したいとします。それらが存在する場合、行には「deadfiled」とマークして、リレーショナル・インテグリティを維持する必要があります。目的は必要なデータだけを保持することです。削除依存関係の検出

削除は1行にのみ影響します。それはカスケード削除を引き起こさないし、私は扶養家族を削除しようとしていない。たとえば、請求書、契約書、変更指示書などの多くの表で、顧客行が参照されている場合、その顧客行には「deadfiled」とマークする必要があります。そのような参照がない場合は、表から顧客行を削除できます。

私はクライアントアプリケーションコードからこれを処理する最善の方法についてアドバイスを探しています。私はPostgreSQL 9.1を使用しています。上記の方法がもろいと考えられている表示されたいくつかの記事では

Begin transation 
delete row x 
if SQLSTATE Error Code = 23503 
    update row set deadfiled = true 
if success 
    commit transaction 
else rollback 

はここで、外部キーの依存関係のPostgresの 『知識』に依存している現在のアプローチ、です。これを行うより良い方法はありますか?

+1

なぜ'deadfiled'を常に設定するだけでなく、依存関係があるかどうかを気にしませんか?ゾンビの行からライブを分離するには、とにかく 'deadfiled'をフィルタリングする必要があります。私はいくつかの行を物理的に削除すると、測定可能なパフォーマンスが向上するとは思わない。 –

+0

またはそれを行い、参照されていない不本意な行を削除する「クリーンアップ」タスクがいくつかあります。 "autovacuum"と呼ぶこともできます;) – araqnid

答えて

1

私は実際にPostgreSQLを使用したことはありませんが、カーソルベースのアプローチを使用しているようです。

代わりにセットベースのソリューションはありますか?

依存関係とフラグそれらのレコードが存在するかどうかをチェック更新クエリを実行します...

update parent 
set deadfiled = true 
where 
    exists (
     select * 
     from dependency1 as d1 
     where d1.id = parent.id 
    ) 
    or 
    exists (
     select * 
     from depenedency2 as d2 
     where d2.id = parent.id 
    ) 
    --or ... etc., keep adding dependency checks 

...そしてフラグがセットされていないところ、それらの削除:

delete from parent where deadfiled = false 
+0

あなたの提案はもちろん機能しますが、リレーションシップが多くのテーブルに接触する場合は、多くのコーディングが必要です。 – Mophilly

+0

あなたの質問を読んで、あなたが私が依存関係を削除していると思っていたことに気付きました。それは意図されたものではありません。 – Mophilly

+0

@Mophillyいいえ、私はあなたが扶養家族ではなく依存しているものを削除したいと思っています。あなたは多くの依存関係があるときに取る努力に関して良い点を挙げる。 –

関連する問題