我问你的意见,知道这是否可行,因为我是菜鸟,也许我正试图以完全错误的方式做到这一点。我搜索了很多但没有发现任何东西,也许没有使用正确的搜索条件 我正在使用Postgresql 9.1。我简化了情况以理解方法
我有3张桌子:
(参见架构)
表A
id_A | data_A
-----+--------
A01 | dataA01
A02 | dataA02
表B
id_B | ref_id_A | data_B
-----+----------+--------
B01 | A01 | dataB01
B02 | A01 | dataB02
B03 | A02 | dataB03
B04 | A02 | dataB04
B05 | A02 | dataB05
B06 | A02 | dataB06
表C
id_C | ref_id_B | data_C
-----+----------+--------
C01 | B01 | dataC01
C02 | B01 | dataC02
C03 | B02 | dataC03
C04 | B02 | dataC04
我要做的是复制链接到表A的所有数据,并使用新ID保存表B和C中存储的所有数据和参考。它应该像复制和粘贴一样工作,以便在处理新的
时维护旧版本重复A01 - > A03
表A
id_A | data_A
-----+--------
A01 | dataA01
A02 | dataA02
A03 | dataA01
表B
id_B | ref_id_A | data_B
-----+----------+--------
B01 | A01 | dataB01
B02 | A01 | dataB02
B03 | A02 | dataB03
B04 | A02 | dataB04
B05 | A02 | dataB05
B06 | A02 | dataB06
B07 | A03 | dataB01
B08 | A03 | dataB02
表C
id_C | ref_id_B | data_C
-----+----------+--------
C01 | B01 | dataC01
C02 | B01 | dataC02
C03 | B02 | dataC03
C04 | B02 | dataC04
C05 | B07 | dataC01
C06 | B07 | dataC02
C07 | B08 | dataC03
C08 | B08 | dataC04
我写了这个查询来复制A01,它在表B中保存了完美的数据,但是我无法复制表C中的数据
WITH new_id_A as
(insert into table_A (id_A, data_A) (select id_A, data_A from table_A where id_A='A01') returning id_A)
insert into table_B (ref_id_A, data_B) select (select id_A from new_id_A) as ref_id_A, data_B from table_B where ref_id_A='A01';
我尝试了不同的方法,但没有结果 我可以使用代码轻松完成任务,但我更愿意在单个事务中在数据库内完成它 谢谢你的关注
答案 0 :(得分:0)
我认为你应该在临时表中为新行暂存ID,以简化:
WITH new_id_A as
(insert into table_A (id_A, data_A) (select id_A, data_A from table_A where id_A='A01') returning id_A)
SELECT 'A01' AS old_id, id_A AS new_id
INSERT INTO TEMP table_A_copy;
insert into table_B (ref_id_A, data_B)
select cp.new_id, b.data_B
from
table_A_copy cp INNER JOIN
table_B b ON b.ref_id_A = cp.old_id;
insert into table_C (ref_id_B, data_B)
select b_new.id_B, c.data_C
from
table_A_copy cp INNER JOIN
table_b b_old on b_old.ref_id_a = cp.old_id inner join
table_b b_new on b_new.ref_id_a = cp.new_id inner join
table_C c ON c.ref_id_B = b_old.id_B;
Fabio更新:
drop table if exists table_a_copy;
create temp table table_a_copy ("old_id" integer, "new_id" integer);
with new_id_a as
(insert into table_a (data_a)
(select data_a from table_a where id_a='1') returning id_a)
insert into table_a_copy select '1'::integer as old_id,
(select * from new_id_a) as new_id;
-- Insert to table B
insert into table_b (ref_id_a, data_b)
select cp.new_id, b.data_b
from
table_a_copy cp inner join
table_b b on b.ref_id_a = cp.old_id;
-- Insert to table C
insert into table_c (ref_id_B, data_C)
select b_new.id_b, c.data_c
from
table_a_copy cp inner join
table_b b_old on b_old.ref_id_a = cp.old_id inner join
table_b b_new on b_new.ref_id_a = cp.new_id inner join
table_c c on c.ref_id_b = b_old.id_b;