[英]How to do an SQL UPDATE based on INSERT RETURNING id in Postgres?
我正在使用Postgres。 我有一张旧桌子和一张新桌子。 旧表中的记录需要在新表中具有相关记录。 新表记录将有效地充当新表中记录的父级。
我正在尝试编写一个迁移,其中旧表中的每个“子”在新表中都将有“父”。
OLD TABLE (我已经添加了一个外键,以期将其作为迁移的一部分进行填充)
id | name | new_id (FK)
----+------+-------------
1 | 1st |
2 | 2nd |
新表
id | name
----+------
|
我需要执行以下操作:
SELECT
旧表中的所有记录 INSERT
记录到新表中的每个旧记录和RETURNING id
RETURNING id
UPDATE
旧记录的外键值 有没有一种方法可以使用设置查询来完成此任务? 还是我需要开始研究诸如LOOP
的Postgres特定内容?
您可以按以下方式使用可写cte:
--open transaction
BEGIN;
--avoid concurrent writes
LOCK old_table IN ROW SHARE MODE;
LOCK new_table IN ROW SHARE MODE;
--create a sequence to populate new_table.id
CREATE SEQUENCE new_table_seq;
--using a writable cte to do the dirty job
WITH old_table_cte AS (
UPDATE old_table SET new_id = nextval('new_table_seq') RETURNING *
)
INSERT INTO new_table SELECT new_id, name FROM old_table_cte;
--Create a proper FK
ALTER TABLE old_table ADD CONSTRAINT old_table_new_table_fk FOREIGN KEY (new_id) REFERENCES new_table (id);
--end transaction
COMMIT;
这种方法有一些好处:
update
。 避免不必要的额外SELECT; 该页面应该可以帮助您:) 最后插入的ID的postgreSQL函数
INSERT INTO tableName (column1, column2) VALUES ('column1val', 'column2val') RETURNING id;
然后,您可以使用返回的ID更新原始行。 您还可以使用该SO页上建议的其他几种方法(如下所述/上面链接)
currval()(如果您知道序列名称),lastval()(用于序列中的最后一个插入),在每个循环中为原始行在选择/插入/更新之间交替或返回ID方法。
使用TEMP表执行迁移。 在更新主表之前,我们应根据需要在TEMP表上处理数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.