postgresql - PG 使用 CTE 和 DML 语句的意外行为

标签 postgresql

我偶然发现了这一点,为了使问题易于解释,我在下面放置了示例代码

表:

CREATE TABLE "MyTab"
(
    "Id" integer NOT NULL DEFAULT nextval('"Anukram"."MyTab_Id_seq"'::regclass),
    "Text1" text COLLATE pg_catalog."default" NOT NULL,
    "Text2" text COLLATE pg_catalog."default" NOT NULL,
    CONSTRAINT "MyTab_pkey" PRIMARY KEY ("Id")
)

数据填写:

INSERT INTO "Anukram"."MyTab" ("Text1","Text2") values
('L','R'),('A','B'),('C','D'), ('L','R1'),('A','B1'),('C','D1')

有问题的陈述:

WITH "Temp" AS (
    UPDATE "MyTab"
    SET "Text2"="Text2" || "Text2"
    WHERE "Text1"='L'
    RETURNING *
)
DELETE 
FROM "MyTab"
USING "Temp"-- <--This is used in some more conditions in where clause not shown here
WHERE "MyTab"."Text1"='L'
RETURNING "MyTab".*

期望:

它应该删除“Text1”列中带有“L”的 2 行

实际:

它只删除一行(查看 RETURNING 语句)

观察:

如果我删除Using子句,一切都会按预期运行

那么我在这里缺少什么?或者这是 PG 使用的快照中的错误?

最佳答案

本例的具体结果令人惊讶,但根本问题is documented :

Trying to update the same row twice in a single statement is not supported. Only one of the modifications takes place, but it is not easy (and sometimes not possible) to reliably predict which one. This also applies to deleting a row that was already updated in the same statement: only the update is performed. Therefore you should generally avoid trying to modify a single row twice in a single statement. In particular avoid writing WITH sub-statements that could affect the same rows changed by the main statement or a sibling sub-statement. The effects of such a statement will not be predictable.

(强调我的。)

简而言之:不要尝试在同一语句中UPDATEDELETE同一行,否则可能会发生奇怪的事情。

关于postgresql - PG 使用 CTE 和 DML 语句的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64817085/

相关文章:

postgresql - 如何解决 GitHub Actions 上 PostgreSQL 的 "permission denied for schema public"错误?

PostgreSQL\d 命令 : Any way to "select" only one column?

postgresql - Mac OSX Lion Postgres 不接受/tmp/.s.PGSQL.5432 上的连接

php - 使用 Doctrine Query Builder 通过内连接查询创建组

postgresql - Postgres ALTER TABLE 的问题

database - 将列添加为外键会导致外键约束中引用的 ERROR 列不存在

postgresql - 如何为标准 jpa2 (hibernate) 创建自定义谓词?

postgresql - 在不同的表列上触发 Postgres 触发器

PostgreSQL - 如何删除用户名中带有连字符的用户

javascript - 如何修复 pg.connect 不是 node.js 上的函数?