给定一个包含下表的 postgreSQL 查询:
+--------------------+
|Foo |
+--------------------+
| id | value1 | refe |
+--------------------+
+--------------------+
|Bar |
+--------------------+
| id | value2 | refe |
+--------------------+
+-------------+
|Refe |
+-------------+
| id | value3 |
+-------------+
其中 refe
列是 Refe
的 id
的外键。现在 Refe
存储与 Foo
和 Bar
(以及可能的其他表)相关的附加数据。
我创建了一个 View 来存储“事件的”refe
,换句话说:Foo
的 refe
字段的联合> 和 条形图
:
CREATE OR REPLACE VIEW liverefe AS
(SELECT refe FROM Foo)
UNION (SELECT refe FROM Bar)
现在,当从 Foo
或 Bar
中删除一行时,refe
有可能失效(没有其他 Foo
或 Bar
行引用它)。在这种情况下,它应该被删除。
可以解释一下如何实现这种“引用计数”触发器吗?
最佳答案
使用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);
(可能)在其中一个引用表中的 DELETE
/UPDATE
之后从 refe 中删除特定行:
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);
带有此类触发器的完整代码示例的相关答案:
如果您有更新 refe
列的习惯,请添加如下触发器:
CREATE TRIGGER foo_updelaft_kill_orphaned_refe
AFTER DELETE <b>OR UPDATE OF refe</b>
ON foo
FOR EACH ROW EXECUTE PROCEDURE f_trg_kill_orphaned_refe();
同样适用于表 bar
等
这样,仅当 UPDATE
实际针对 refe
列时才会调用触发器。
关于sql - PostgreSQL 中的 "Reference counting"触发器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25184726/