114

外部キーを含む行を削除したいのですが、次のようにしようとすると、次のようになります。

DELETE FROM osoby WHERE id_osoby='1'

私はこの声明を受け取ります:

エラー:テーブル"osoby"の更新または削除がテーブル"kontakty"の外部キー制約"kontakty_ibfk_1"に違反しています詳細:キー(id_osoby)=(1)はテーブル"kontakty"から引き続き参照されています。

これらの行を削除するにはどうすればよいですか?

4

5 に答える 5

129

これを自動化するには、外部キー制約を で定義できますON DELETE CASCADE外部キー制約のマニュアル
を引用します:

CASCADE参照された行が削除されると、それを参照している行も自動的に削除されるように指定します。

次のように現在の FK 定義を検索します。

SELECT pg_get_constraintdef(oid) AS constraint_def
FROM   pg_constraint
WHERE  conrelid = 'public.kontakty'::regclass  -- assuming public schema
AND    conname = 'kontakty_ibfk_1';

ON DELETE ...次に、次のようなステートメントでその部分を追加または変更しON DELETE CASCADEます (他のすべてをそのまま保持します)。

ALTER TABLE kontakty
   DROP CONSTRAINT kontakty_ibfk_1
 , ADD  CONSTRAINT kontakty_ibfk_1
   FOREIGN KEY (id_osoby) REFERENCES osoby (id_osoby) ON DELETE CASCADE;

ALTER CONSTRAINTコマンドはありません。制約を削除して 1 つのALTER TABLEステートメントで再作成し、同時書き込みアクセスで発生する可能性のある競合状態を回避します。

明らかに、そうするには特権が必要です。この操作はACCESS EXCLUSIVEtable のロックと tablekontaktySHARE ROW EXCLUSIVEロックを取得しますosoby

ALTERテーブルを削除できない場合は、手動で (1 回) またはトリガーBEFORE DELETEで (毎回) 削除することが残りのオプションです。

于 2013-01-06T12:55:45.417 に答える
43

外部キーがまだ別のテーブルを参照している場合、その外部キーを削除することはできません。最初に参照を削除します

delete from kontakty
where id_osoby = 1;

DELETE FROM osoby 
WHERE id_osoby = 1;
于 2013-01-06T12:32:01.523 に答える
30

この質問が出されてからしばらく経ちましたが、希望が助けになります。db 構造を変更または変更することはできないため、これを行うことができます。postgresql docsによると。

TRUNCATE -- テーブルまたはテーブルのセットを空にします。

TRUNCATE [ TABLE ] [ ONLY ] name [ * ] [, ... ]
    [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]

説明

TRUNCATE は、一連のテーブルからすべての行をすばやく削除します。各テーブルに対して非修飾の DELETE と同じ効果がありますが、実際にはテーブルをスキャンしないため、より高速です。さらに、後続の VACUUM 操作を必要とせずに、ディスク領域をすぐに再利用します。これは、大きなテーブルで最も役立ちます。


テーブル othertable を切り捨て、外部キー制約を介して othertable を参照するテーブルにカスケードします。

TRUNCATE othertable CASCADE;

同様に、関連するシーケンス ジェネレーターもリセットします。

TRUNCATE bigtable, fattable RESTART IDENTITY;

関連するすべてのシーケンス ジェネレーターを切り捨ててリセットします。

TRUNCATE revinfo RESTART IDENTITY CASCADE ;
于 2016-10-18T14:19:35.947 に答える
8

これは、削除したいkontakty行を参照している行がtable にあることを意味します。osoby最初にその行を削除するか、テーブル間のリレーションにカスケード削除を設定する必要があります。

ポウォゼニア!

于 2013-01-06T12:30:31.807 に答える