私はこれらのテーブルを持っています:
イベント (evt_id、evt_code、reg_id) マグニチュード(mag_id、evt_id、value) トレース (trace_id、pt_id) ポイント (pt_id、evt_id)
に関連するすべてのテーブルからすべての行を削除したいevt_id=1139
。
どうすればいいのですか?
私はこれらのテーブルを持っています:
イベント (evt_id、evt_code、reg_id) マグニチュード(mag_id、evt_id、value) トレース (trace_id、pt_id) ポイント (pt_id、evt_id)
に関連するすべてのテーブルからすべての行を削除したいevt_id=1139
。
どうすればいいのですか?
スキーマを制御できる場合は、スキーマでカスケード削除を使用します。
記事から(あなたの例のために翻訳されたより適切な部分)
CREATE TABLE point
(
pt_id integer PRIMARY KEY,
evt_id integer REFERENCES event ON DELETE CASCADE
)
カスケードが設定されている場合は、メイン イベント テーブルから削除するだけで、他のすべてのテーブルが自動的にクリーンアップされます。
それ以外の場合は、最初にすべての参照を削除してから、メイン テーブルを削除する必要があります。データの一貫性を保つために、これを 1 つのトランザクションで行う必要があります
BEGIN;
DELETE FROM trace WHERE EXISTS
(SELECT 1 FROM point WHERE evt_id = 1139 AND trace.pt_id = point.pt_id);
DELETE FROM point where evt_id = 1139;
DELETE FROM magnitude where evt_id = 1139;
DELETE FROM event where evt_id = 1139;
COMMIT;
質問の重要な要素は、テーブルからの削除だけtrace
です。trace.pt_id
参照していると仮定しても安全だと思いますpoint.pt_id
か?
で外部キーをON DELETE CASCADE
定義し、テーブルを忘れてしまうかtrace
(@kevinですでに指摘されているように)、行の依存関係を手動で処理する必要があります。
PostgreSQL 9.1以降、データ変更CTEを使用できます。
BEGIN;
WITH x AS (
DELETE FROM point WHERE evt_id = 1139
RETURNING pt_id
)
DELETE FROM trace
USING x
WHERE trace.pt_id = x.pt_id;
DELETE FROM magnitude WHERE evt_id = 1139;
DELETE FROM event WHERE evt_id = 1139;
COMMIT;
影響を受けるすべての戻り値のRETURNING句-これらは、対応するすべての行をから削除するために使用されます。DELETE FROM point
pt_id
trace
あなたは、並行性があなたのケースで問題であるかどうかについて言及しませんでした。もしそうなら、そして削除の間の短い時間枠で起こり得る結果を避けたいなら、の行が別のテーブルからすでに削除されている間にあるテーブルに存在する場合、それをすべてトランザクションevt_id = 1139
にラップします。
それが気にならない場合は、無視してください。BEGIN
COMMIT
デッドロックを回避するには、(すべての同時トランザクションで)常に同じシーケンスの削除ステートメントを使用します。これにより、1つのトランザクションが一方のテーブルで削除を開始し、次のトランザクションがもう一方のテーブルで削除を開始し、それぞれがもう一方のテーブルを待機する状況を回避できます。
削除する行を階層として想定できる場合は、ON DELETE CASCADE 句を使用して関係に対して FOREIGN KEY 制約を定義できます。一番上の行を削除すると、カスケードダウンしてすべて削除されます。
http://www.postgresql.org/docs/9.1/static/ddl-constraints.html#DDL-CONSTRAINTS-FK
異なるテーブルのIDが対応しており、リンクに使用されていると思います。また、evt_idに間接的にリンクされているだけですが、すべてのトレースポイントを削除したいとします。
次のようにして、すべてのテーブルからレコードを削除できます。
DELETE event , magnitude, trace, point
FROM event left join magnitude on event.evt_id = magnitude.evt_id
left join point on event.evt_id = point.evt_id
left join trace on point.pt_id = trace.trace_id
where event_id=1139
$delete = 1139;
$query = "DELETE FROM event, magnitude, point WHERE evt_id = '$delete'";
mysql_query($query, $con);
$query = "DELETE FROM trace WHERE pt_id = '$delete'";
または、そのステートメントを .sql ファイルに貼り付けて実行するか、SQL ソフトウェアのクエリ ウィンドウに貼り付けるか、.php ファイルに配置してサーバーで実行します。