I have these tables:
event (evt_id, evt_code, reg_id) magnitude (mag_id, evt_id, value) trace (trace_id, pt_id) point (
The only non-trivial element in your question are deletes from the table trace
. I guess it is safe to assume trace.pt_id
is referencing point.pt_id
?
Either you define a foreign key with ON DELETE CASCADE and just forget about the table trace
(as already pointed out by @kevin) or you have to take care of depending rows manually.
Since PostgreSQL 9.1 you can use data-modifying CTEs:
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;
The RETURNING clause of the DELETE FROM point
returns all affected pt_id
- those are in turn used to delete all corresponding rows from trace
.
You did not mention whether concurrency is a problem in your case. If it is, and if you want to avoid possible results in the short time window in between deletes where rows for evt_id = 1139
are present in one table while already deleted from another, wrap it all into a transaction.
If that is no concern to you, ignore BEGIN
and COMMIT
.
To avoid deadlocks always use the same sequence of delete statements (in all concurrent transactions). This avoids situations where one transaction would start deleting in one table, the next in the other table and then each would wait for the other.