我有这些表格:
event (evt_id, evt_code, reg_id) magnitude (mag_id, evt_id, value) trace (trace_id, pt_id) point (pt_id, evt_id)
我想删除与evt_id=1139
相关的所有表格中的所有行
我该怎么做?
答案 0 :(得分:18)
如果您可以控制架构,我会使架构使用cascading deletes。
从文章(为您的示例翻译的更相关的部分)
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;
答案 1 :(得分:11)
您问题中唯一的重要元素是表trace
中的删除。我想可以安全地假设trace.pt_id
引用了point.pt_id
?
要么定义foreign key with ON DELETE CASCADE
而忘记表trace
(已经是pointed out by @kevin),要么必须手动处理依赖行。
自PostgreSQL 9.1 以来,您可以使用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;
DELETE FROM point
的{{3}}会返回所有受影响的pt_id
- 这些用于删除trace
中的所有相应行。
您没有提及并发在您的案例中是否存在问题。如果是,并且如果您希望在删除之间的短时间窗口中避免可能的结果,其中evt_id = 1139
的行存在于一个表中而已从另一个表中删除,则将其全部包装到事务中。
如果您不关心这一点,请忽略BEGIN
和COMMIT
。
要避免死锁,请始终使用相同的删除语句序列(在所有并发事务中)。这可以避免一个事务在一个表中开始删除,另一个表中的下一个事务处理,然后每个事务将等待另一个事务的情况。
答案 2 :(得分:4)
如果要删除的行可以设想为层次结构,则可以为ON DELETE CASCADE子句的关系定义FOREIGN KEY约束。删除顶部的行将向下级联并将其全部删除。
http://www.postgresql.org/docs/9.1/static/ddl-constraints.html#DDL-CONSTRAINTS-FK
答案 3 :(得分:-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
答案 4 :(得分:-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文件中并在服务器上运行。