Postgres规则防止CTE查询

Jef*_*f G 6 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
Run Code Online (Sandbox Code Playgroud)

运行时,我收到错误

"错误:WITH不能在由规则重写为多个查询的查询中使用".

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

INSERT INTO foo SELECT * FROM (VALUES (1), (2)) a
Run Code Online (Sandbox Code Playgroud)

有没有人知道另一种方法可以完成我试图做的事情,除了1)使用规则,阻止使用"with"查询,或2)使用行级触发器?谢谢,         

Den*_*rdy 4

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

一般来说,除非规则是绝对必要的,否则更喜欢触发器而不是规则。(实际上,它们从来都不是。)

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

此外,偶尔也会有人谈论彻底弃用 Postgres 规则:

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