【问题标题】:Why don't I see changes done in CTE?为什么我看不到 CTE 中所做的更改?
【发布时间】:2019-12-24 16:15:12
【问题描述】:
create table tab(id int);

insert into tab(id) values(1);

with x as (delete from tab where id = 1 returning id),
y as (select * from tab where id in (select id from x))
select * from y;

-- outputs a row with "1"
-- i need no rows returned

为什么在y CTE 子查询中仍然看到已删除的行? xy 部分应按顺序执行,因为 y 依赖于 x。您能否向我解释一下为什么我看不到 x 的变化?我应该怎么做才能见到他们?

我不确定它是否与隔离级别有关,因为一切都在同一个查询中完成 => 同一个事务

谢谢!

【问题讨论】:

    标签: sql postgresql common-table-expression


    【解决方案1】:

    这种行为记录在"7.8.2. Data-Modifying Statements in WITH"

    (...)

    WITH 中的子语句与每个子语句同时执行 其他与主查询。因此,当使用数据修改 WITH 中的语句,指定更新的顺序 实际发生是不可预知的。所有语句都执行 相同的快照(见Chapter 13),所以他们 无法“看到”彼此对目标表的影响。 (...)

    (...)

    要从表中删除并在一个查询中使用表的架构获得空结果,只需在 CTE 中删除并使用错误的 WHERE 子句从表中选择。

    WITH
    cte
    AS
    (
    DELETE FROM tab
           WHERE id = 1 
    )
    SELECT *
           FROM tab
           WHERE false;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-09
      • 2022-07-06
      • 1970-01-01
      • 2019-11-04
      • 1970-01-01
      • 2012-08-18
      • 1970-01-01
      相关资源
      最近更新 更多