给定一个包含以下表的postgreSQL查询:

+--------------------+
|Foo                 |
+--------------------+
| id | value1 | refe |
+--------------------+

+--------------------+
|Bar                 |
+--------------------+
| id | value2 | refe |
+--------------------+

+-------------+
|Refe         |
+-------------+
| id | value3 |
+-------------+

其中refe列是idRefe外键。现在Refe存储与FooBar相关的附加数据(以及潜在的其他表)。
我创建了一个存储“active”的视图,换句话说:referefeFoo字段的并集:
CREATE OR REPLACE VIEW liverefe AS
        (SELECT refe FROM Foo)
        UNION (SELECT refe FROM Bar)

现在,当从BarFoo中删除一行时,Bar可能会死掉(没有其他refeFoo行引用它)。在这种情况下,它应该被移除。
我们能解释一下如何实现这样的“引用计数”触发器吗?

最佳答案

使用NOT EXISTS反半连接。
要删除refe中的所有死行:

DELETE FROM refe r
WHERE NOT EXISTS (SELECT 1 FROM foo WHERE refe = r.id)
AND   NOT EXISTS (SELECT 1 FROM bar WHERE refe = r.id);

(可能)从refe中删除一个引用表中DELETE/UPDATE之后的特定行:
DELETE FROM refe r
WHERE r.id = 12345   -- your id here
AND   NOT EXISTS (SELECT 1 FROM foo WHERE refe = r.id)
AND   NOT EXISTS (SELECT 1 FROM bar WHERE refe = r.id);

与此触发器的完整代码示例相关的答案:
Foreign key contraints in many-to-many relationships
如果您应该在更新refe列的habbit中,请添加如下触发器:
CREATE TRIGGER foo_updelaft_kill_orphaned_refe
AFTER DELETE OR UPDATE OF refe
ON foo
FOR EACH ROW EXECUTE PROCEDURE f_trg_kill_orphaned_refe();

同样适用于表bar等。
这样,只有当UPDATE实际指向refe列时才会调用触发器。
Details in the manual.

10-08 12:55