使用其他表上的插入内容返回的ID更新表

问题描述

我试图弄清楚如何将Table1中的数据插入Table2,然后使用Table2中新创建的ID更新Table1中的相应行。

我正在使用Postgres 12.4来实现它的价值

示例: 我有两个桌子,例如usersMetadata

用户表具有以下列

| id | info | Metadata_id |

元数据表具有以下列

| id | data |

我想将所有info值从users表迁移到data表的Metadata列,并更新我的users.Metadata_id(当前为空白),并带有相应的Metadata.id值,实际上是回填外键。

有什么方法可以优雅地完成此任务吗?我有一个有效的查询,该查询可锁定两个表并创建一个临时序列以插入到Metadata.idusers.Metadata_id中,但这似乎很脆弱,我需要在ID中现有的最高ID之后开始序列元数据表,这是不理想的。

我还尝试过使用带有RETURNING子句的数据修改CTE来更新users表,但无法使其正常工作。

解决方法

此处不能使用returning,因为插入时需要跟踪用户和元数据的关联。

我认为首先使用nextval()在CTE中预先生成每个用户的元数据序列会更简单。然后,您可以使用该信息将其插入元数据并更新用户表:

with 
    candidates as (
        select u.*,nextval(pg_get_serial_sequence('metadata','id')) new_metadata_id
        from users u
    ),inserted as (
        insert into metadata (id,data) overriding system value
        select new_metadata_id,info from candidates
    )
update users u
set metadata_id = c.new_metadata_id
from candidates c
where c.id = u.id   

我们需要overriding system value语句中的insert子句,以便Postgres允许我们写入serial列。

Demo on DB Fiddle