如何在Postgres中基于插入返回id进行SQL更新?
我在用Postgres。我有一张旧桌子和一张新桌子。旧表中的记录需要在新表中有相关记录。新表记录实际上将充当新表中记录的父记录 我正在尝试编写一个迁移,其中旧表中的每个“子”将在新表中具有“父” 旧表(我添加了一个外键,以作为迁移的一部分填充它) 新表格如何在Postgres中基于插入返回id进行SQL更新?,sql,postgresql,migration,database-migration,Sql,Postgresql,Migration,Database Migration,我在用Postgres。我有一张旧桌子和一张新桌子。旧表中的记录需要在新表中有相关记录。新表记录实际上将充当新表中记录的父记录 我正在尝试编写一个迁移,其中旧表中的每个“子”将在新表中具有“父” 旧表(我添加了一个外键,以作为迁移的一部分填充它) 新表格 id | name ----+------ | 我需要做以下工作: 从旧表中选择所有记录 为每个旧记录在新表中插入一条记录,并返回id 使用返回的id更新旧记录的外键值 有没有一种方法可以使用集合查询来实现这一点?或者我需要开
id | name
----+------
|
我需要做以下工作:
从旧表中选择所有记录
为每个旧记录在新表中插入一条记录,并
返回id
使用返回的id更新旧记录的外键值
有没有一种方法可以使用集合查询来实现这一点?或者我需要开始钻研Postgres的具体内容,比如
LOOP
s?这一页应该可以帮助你:)
然后可以使用返回的id更新原始行。您还可以使用该SO页面上建议的其他一些方法(如下所述/上面链接)
currval()如果您知道序列名称,则lastval()表示序列中的最后一次插入,在原始行的每个循环中选择/插入/更新,或返回id方法之间进行交替 您可以使用可写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
- 并发安全李>
- 延迟FK创建将导致更快的脚本李>
- 采用纯SQL解决方案,无需使用过程语言李>
- 避免在同一步骤中读取和写入旧的_表
返回id
,但我需要对旧表中的每条记录执行此操作。这就是我应该如何迭代旧表中的记录,你需要使用序列来完成你想用Postgresql做的事情
INSERT INTO tableName (column1, column2) VALUES ('column1val', 'column2val') RETURNING id;
--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;