我正在尝试在 Postgres 8.4 中创建一个使用 CTE 内部的 plpgsql 函数,但它给了我一个语法错误。他们不允许吗?
(像这样,请记住,我是在没有代码的情况下编写的。)
With foo as (SELECT id,a as alias FROM foo);
UPDATE zoo SET b = alias FROM foo WHERE id = foo.id;
^Error here
我正在尝试在 Postgres 8.4 中创建一个使用 CTE 内部的 plpgsql 函数,但它给了我一个语法错误。他们不允许吗?
(像这样,请记住,我是在没有代码的情况下编写的。)
With foo as (SELECT id,a as alias FROM foo);
UPDATE zoo SET b = alias FROM foo WHERE id = foo.id;
^Error here
WITH foo as (
SELECT id
, a AS zalias
FROM footable
)
UPDATE zoo z
SET b = f.zalias
FROM foo f
WHERE z.id = f.id
;
注意:“别名”是保留字。
根据 Erwin Brandstetter 的评论更新:CTE 在 8.4 的 UPDATE 语句中无效。您需要 9.1 或更高版本。由于 CTE 实际上是一种即时视图,因此您可以将 CTE 主体放在视图中,然后引用它。
CREATE VIEW foo as (
SELECT id
, a AS zalias
FROM footable
);
UPDATE zoo z
SET b = f.zalias
FROM foo f
WHERE z.id = f.id
;
DROP VIEW foo;
PostgreSQL 8.4 中不提供修改 CTE的数据(就是这样)。
正如@wildplasser 在 PostgreSQL 9.1或更高版本中所展示的那样,您的声明将适用于小补丁,其中引入了数据修改 CTE。
一个非常简单的 8.4 替代品是子查询:
UPDATE zoo z
SET b = f.alias
FROM (SELECT id, a as alias FROM foo) f
WHERE z.id = f.id;
该示例可以进一步简化(但现实世界的情况可能更复杂):
UPDATE zoo z
SET b = f.a
FROM foo f
WHERE z.id = f.id;
id
请记住在WHERE
子句中对其他不明确的列名进行表限定。