25

我有这些表:

事件     (evt_id、evt_code、reg_id)

幅度(mag_id,evt_id,值)

跟踪     (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
)

如果您设置了级联,那么您只需从主事件表中删除,所有其他表将被自动清理

否则,您需要先删除所有引用,然后再删除主表。您应该在一个事务中执行此操作以保持数据一致

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

您问题中唯一重要的元素是 deletes from the table 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存在于一个表中而已经从另一个表中删除,请将其全部包装到一个事务中。
如果这与您无关,请忽略BEGINand COMMIT

为避免死锁,请始终使用相同的删除语句序列(在所有并发事务中)。这避免了一个事务开始在一个表中删除,下一个在另一个表中开始删除,然后每个事务都将等待另一个事务的情况。

于 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 回答