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

时间:2018-04-10 22:04:02

标签: sql postgresql migration database-migration

我正在使用Postgres。我有一张旧桌子和一张新桌子。旧表中的记录需要在新表中包含相关记录。新表记录实际上将充当新表中记录的父级。

我正在尝试编写一个迁移,其中每个"孩子"从旧表中将有#34; parent"在新表中。

OLD TABLE (我已经添加了一个外键,希望在迁移过程中填充它)

 id | name | new_id (FK)
----+------+-------------
  1 | 1st  | 
  2 | 2nd  |

NEW TABLE

 id | name 
----+------
    |

我需要做以下事情:

  • SELECT旧表中的所有记录
  • INSERT每条旧记录和RETURNING id
  • 的新表格记录
  • UPDATE旧记录的外键值RETURNING id

有没有办法使用set查询来完成此操作?或者我是否需要开始深入研究Postgres特定的事情,如LOOP s?

3 个答案:

答案 0 :(得分:2)

您可以按如下方式使用可写的cte:

 http://www.mkyong.com/webservices/jax-ws/suncertpathbuilderexception-unable-to-find-valid-certification-path-to-requested-target/

这种方法有一些好处:

  • 按照您的要求利用RETURNING,但在--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; 步骤中。避免不必要的 额外的SELECT;
  • 并发安全;
  • 推迟FK创建将导致更快的脚本;
  • 使用纯SQL解决方案,无需使用过程语言;
  • 在同一步骤中避免对old_table进行读写。

答案 1 :(得分:-1)

此页面可以帮助您:) postgreSQL function for last inserted ID

INSERT INTO tableName (column1, column2) VALUES ('column1val', 'column2val') RETURNING id;

然后,您可以使用返回的ID更新原始行。您还可以使用该SO页面上建议的其他一些方法(下面提到/上面链接)

currval()如果您知道序列名称,lastval()用于序列中的最后一次插入,则在原始行的每个循环中的select / insert / update之间交替,或者RETURNING id方法。

答案 2 :(得分:-1)

使用TEMP表执行迁移。在主表上更新之前,我们应该根据需要在TEMP表上操作数据。