我正在使用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?
答案 0 :(得分:2)
您可以按如下方式使用可写的cte:
http://www.mkyong.com/webservices/jax-ws/suncertpathbuilderexception-unable-to-find-valid-certification-path-to-requested-target/
这种方法有一些好处:
--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; 答案 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表上操作数据。