繁体   English   中英

如何在Postgres中基于INSERT RETURNING id进行SQL更新?

[英]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;

这种方法有一些好处:

  • 根据您的要求利用RETURNING的优势,但要进行update 避免不必要的额外SELECT;
  • 并发安全;
  • 推迟FK的创建将使脚本速度更快;
  • 使用纯SQL解决方案,无需使用过程语言;
  • 避免在同一步骤中读写old_table。

该页面应该可以帮助您:) 最后插入的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM