使用 Postgres 10.5,给出以下内容:
postgres=# begin;
with updated as (update bippy set id = 100 where id = 1 returning 1)
select id, ts from bippy;
commit;
BEGIN
id | ts
----+-------------------------------
66 | 2019-07-09 10:42:32.062496-04
80 | 2019-07-09 10:43:28.068512-04
80 | 2019-07-09 10:43:28.596341-04
80 | 2019-07-15 14:42:32.062496-04
1 | 2019-07-09 10:42:23.142809-04
1 | 2019-07-09 10:42:25.366664-04
1 | 2019-07-09 10:42:26.142027-04
1 | 2019-07-09 10:42:26.702398-04
(8 rows)
COMMIT
为什么上面返回一个id
of1
而不是100
,即根据公用表表达式?
当我立即从表中选择时,我看到更新已经发生。
postgres=# select * from bippy;
ts | id
-------------------------------+-----
2019-07-09 10:42:32.062496-04 | 66
2019-07-09 10:43:28.068512-04 | 80
2019-07-09 10:43:28.596341-04 | 80
2019-07-15 14:42:32.062496-04 | 80
2019-07-09 10:42:23.142809-04 | 100
2019-07-09 10:42:25.366664-04 | 100
2019-07-09 10:42:26.142027-04 | 100
2019-07-09 10:42:26.702398-04 | 100
(8 rows)
您需要查询 CTE 并返回 * 以查看更改的数据。
或者,如果您希望返回所有行(更新和未更新):
从文档中:
7.8.2. WITH 中的数据修改语句
WITH 中的子语句彼此同时执行,并与主查询同时执行。因此,当在 WITH 中使用数据修改语句时,指定更新实际发生的顺序是不可预测的。所有语句都使用同一个快照执行(参见第 13 章),因此它们无法“看到”彼此对目标表的影响。这减轻了行更新的实际顺序的不可预测性的影响,并且意味着返回数据是在不同的 WITH 子语句和主查询之间传达更改的唯一方法。这方面的一个例子是
外部 SELECT 将在 UPDATE 操作之前返回原始价格,而在
外部 SELECT 将返回更新的数据。