postgresql - 防止 CTE 查询的 Postgres 规则

标签 postgresql postgresql-9.3

使用 Postgres 9.3:

我试图在对另一个表执行插入操作时自动填充一个表。这似乎是规则的一个很好的用途,但是在将规则添加到第一个表之后,我无法再使用可写 CTE 对第二个表执行插入。这是一个例子:

CREATE TABLE foo (
    id INT PRIMARY KEY
);

CREATE TABLE bar (
    id INT PRIMARY KEY REFERENCES foo
);

CREATE RULE insertFoo AS ON INSERT TO foo DO INSERT INTO bar VALUES (NEW.id);

WITH a AS (SELECT * FROM (VALUES (1), (2)) b)
INSERT INTO foo SELECT * FROM a

运行时出现错误

"ERROR: WITH cannot be used in a query that is rewritten by rules into multiple queries".

我已经搜索了那个错误字符串,但我只能找到源代码的链接。我知道我可以使用行级触发器执行上述操作,但似乎我应该能够在语句级别执行此操作。为什么我不能使用可写 CTE,当这样的查询可以(在这种情况下)很容易地重写为:

INSERT INTO foo SELECT * FROM (VALUES (1), (2)) a

除了 1) 使用规则,防止使用“with”查询,或 2) 使用行级触发器之外,有没有人知道另一种方法可以完成我正在尝试做的事情?谢谢,

最佳答案

TL;DR:使用触发器,而不是规则。

一般来说,触发器优先于规则,除非规则是绝对必要的。 (实际上,它们从来都不是。)

使用规则会带来大量问题,这些问题会不必要地使您以后的生活复杂化。你在这里遇到了一个。另一个(主要)是,例如,受影响的行数将对应于最后一个查询的行数——如果您在某处依赖 FOUND 并且您的查询错误地报告没有行受到查询的影响,你会遇到痛苦的错误。

此外,偶尔会谈到完全弃用 Postgres 规则:

http://postgresql.nabble.com/Deprecating-RULES-td5727689.html

关于postgresql - 防止 CTE 查询的 Postgres 规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26268322/

相关文章:

php - 日期字符串不会转换为时间戳

database - Postgres 统计收集

python - 运行时实体上的 sqlalchemy 动态模式

postgresql - 如何将 Postgres SQL 数据读入 Grafana 图中

postgresql - 为什么 postgres 的日期范围上限函数会返回一个独占边界?

sql - 关系不存在 PLPGSQL

sql - 仅返回列中的数值 - Postgresql

json - 使用 pg-promise 格式化 JSON 输出,将外键封装为对象

sql - 在 SQL 中计算文档频率

postgresql - 什么时候使用多列索引?