postgresql 带有FROM和ctids的update语句

r7s23pms  于 2023-06-05  发布在  PostgreSQL
关注(0)|答案(1)|浏览(226)

我有一份更新声明,格式如下(简化):

UPDATE changes.table1 a
        SET checked_out_at = a.checked_out_at
       FROM unified.view2 b
      WHERE a.ctid = '(4,48)'
        AND b.some_pkey = a.some_pkey
  RETURNING *;

此语句将无法更新。我运行它时看到0 rowsUPDATE 0。但是如果我通过删除连接表来修改它,更新将通过(只有一次,ctid毕竟改变了,我需要找到新的):

UPDATE changes.table1 a
        SET checked_out_at = a.checked_out_at
      WHERE a.ctid = '(4,48)'
  RETURNING *;

不幸的是,我需要连接表来存放RETURNING子句中的一些数据。
为什么这两个特性不兼容?连接的行是否有与单个表不同的ctid?我知道我对所有的低级系统列都没有正确的理解,但是这看起来仍然很简单。这个或类似的东西可以工作吗?

h5qlskok

h5qlskok1#

如果目标是限制更新的行数,请考虑使用如下子查询:

UPDATE changes.table1 a
   SET checked_out_at = a.checked_out_at
  FROM (SELECT c.ctid AS original_ctid, b.*
          FROM changes.table1 c
          JOIN unified.view2 b
            ON b.some_pkey = a.some_pkey
         LIMIT 10) d
 WHERE a.ctid = d.original_ctid
RETURNING *;

这将限制更新行的数量,同时避免额外的表或索引扫描,因为TID扫描将用于查找要更新的行。它还消除了在单独查询中确定CTID的需要。

相关问题