【问题标题】:Delete table rows depending upon rows deleted in another table根据在另一个表中删除的行删除表行
【发布时间】:2012-06-15 08:20:39
【问题描述】:

我有两张桌子t1t2。我正在以这种方式删除t2 的某些行:

delete from t2 where expiry < NOW();

t1t2 共有一个列 id。执行上述语句时,我还想删除t1中的相应行(如果有)(可能没有)。

如何做到这一点?
是否可以为这两个操作编写一个查询?

【问题讨论】:

标签: sql postgresql triggers


【解决方案1】:

我看到至少三种好方法 - 取决于您的问题中缺少的更多细节。我以你的例子为基础:

  • t2 是母表
  • t1孩子

1。 Foreign key constraintON CASCADE DELETE

试验台:

CREATE TABLE t2 (
  id serial PRIMARY KEY  -- primary or unique key needed
, expiry timestamp
);

CREATE TABLE t1 (
  id int references t1(id) ON DELETE CASCADE  -- ON UPDATE CASCADE, too?
);

填充表:

INSERT INTO t2(expiry)
SELECT (now() + g * interval '1h')
FROM   generate_series(1, 10) g;   -- 10 arbitrary rows

INSERT INTO t1(id)
SELECT id FROM t2 WHERE id%2 = 0;  -- pick even numbers for t1

SELECT * FROM t1;

如果您从 t2 中删除行,则会自动删除 t1 中的相应行:

DELETE FROM t2 WHERE id IN (1,2,3,4,5);
-- rows 2,4 in `t1` are deleted automatically

将这样的外键约束添加到现有表中:

ALTER TABLE t1 ADD CONSTRAINT t1_id_fkey FOREIGN KEY (id)
REFERENCES t2 (id) ON DELETE CASCADE;

当然,外键需要t1.id 上的唯一键或主键。但在这样的场景中,您可能会遇到这种情况。

2。 Trigger AFTER DELETE

如果t2.id 中的值不是唯一的,或者t1.id 中的值违反了外键约束,则可以改为在删除后创建触发器。

触发功能:

CREATE OR REPLACE FUNCTION t2_delaft
  RETURNS trigger 
  LANGUAGE plpgsql AS
$func$
BEGIN
   DELETE FROM t1
   WHERE  t1.id = OLD.id;

   RETURN NULL;  -- AFTER trigger can return NULL
END
$func$

触发器:

CREATE TRIGGER delaft
AFTER DELETE ON t2
FOR EACH ROW EXECUTE PROCEDURE t2_delaft();

您还可以实现RULE。但我发现触发器通常更容易处理。

3。 Data modifying CTE

请原谅我最后给出了最简单的答案。无论如何,这都有效 - 只要您使用的是 PostgreSQL 9.1 或更高版本

WITH x AS (
    DELETE FROM t1
    WHERE  id IN (1,2,3,4,5)
    RETURNING id
    )
DELETE FROM t2
USING  x
WHERE  t2.id = x.id;

【讨论】:

  • 我在 t1 中的外键约束类似于 - FOREIGN KEY (b, c) REFERENCES t2 (c1, c2)。所以我给出了这样的删除级联 - FOREIGN KEY (b, c) REFERENCES t2 (c1, c2) ON DELETE CASCADE。但现在在删除之前,我想将要从表 t1 中删除的行复制到另一个表(与 t1 具有相同列的永久表),然后删除。那么在 ON DELETE CASCADE 之前我应该​​给出什么。
  • 你不认为这是一个完全不同的问题吗?
  • @Ashwin:逻辑规定 fk 约束只能级联 UPDATEDELETE。触发自动备份副本到另一个表是完全不同的事情。您可以找到类似的问题(和答案)here on SOhere on dba.SE。如果这不包括您的情况,我建议您发布新问题。
猜你喜欢
  • 2010-12-19
  • 1970-01-01
  • 2010-12-08
  • 2018-10-16
  • 1970-01-01
  • 1970-01-01
  • 2017-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多