25

私はこれらのテーブルを持っています:

イベント     (evt_id、evt_code、reg_id)

マグニチュード(mag_id、evt_id、value)

トレース     (trace_id、pt_id)

ポイント     (pt_id、evt_id)

に関連するすべてのテーブルからすべての行を削除したいevt_id=1139
どうすればいいのですか?

4

5 に答える 5

22

スキーマを制御できる場合は、スキーマでカスケード削除を使用します。

記事から(あなたの例のために翻訳されたより適切な部分)

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;
于 2012-04-13T17:11:11.373 に答える
15

質問の重要な要素は、テーブルからの削除だけ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 pointpt_idtrace

あなたは、並行性があなたのケースで問題であるかどうかについて言及しませんでした。もしそうなら、そして削除の間の短い時間枠で起こり得る結果を避けたいなら、の行が別のテーブルからすでに削除されている間にあるテーブルに存在する場合、それをすべてトランザクションevt_id = 1139にラップします。 それが気にならない場合は、無視してください。
BEGINCOMMIT

デッドロックを回避するには、(すべての同時トランザクションで)常に同じシーケンスの削除ステートメントを使用します。これにより、1つのトランザクションが一方のテーブルで削除を開始し、次のトランザクションがもう一方のテーブルで削除を開始し、それぞれがもう一方のテーブルを待機する状況を回避できます。

于 2012-04-13T19:31:40.347 に答える
5

削除する行を階層として想定できる場合は、ON DELETE CASCADE 句を使用して関係に対して FOREIGN KEY 制約を定義できます。一番上の行を削除すると、カスケードダウンしてすべて削除されます。

http://www.postgresql.org/docs/9.1/static/ddl-constraints.html#DDL-CONSTRAINTS-FK

于 2012-04-13T17:56:40.293 に答える
-3

異なるテーブルの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
于 2012-04-13T17:22:16.210 に答える
-4
$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 ファイルに配置してサーバーで実行します。

于 2012-04-13T17:13:04.753 に答える