使用Oracle,有没有办法将值从一个表插入到另一个表中,然后从插入的表中获取标识值并更新原始列中的列?
TABLE_1为空
ID VALUE
-----------
TABLE_2的值......
ID VALUE
-----------
0 Val 1
0 Val 2
0 Val 3
...插入TABLE_1(带有标识列)
ID VALUE
-----------
1 Val 1
2 Val 2
3 Val 3
然后使用ID
更新TABLE_2ID VALUE
-----------
1 Val 1
2 Val 2
3 Val 3
答案 0 :(得分:2)
您需要获得此类要求的程序。此解决方案使用SELECT ... FOR UPDATE来锁定源表,以防止另一个会话占用我们想要提供新ID的记录。它还为我们提供了WHERE CURRENT OF语法,这使我们可以轻松识别需要更新的记录。
此解决方案假设存在用于填充标识列的序列。我们还有其他选项(包括12C中的自动增量),但RETURNING子句是阻止新值的关键。
declare
cursor c2 is
select * from table2
for update of id;
r2 c2%rowtype;
new_id t1.id%type;
begin
open c2;
loop
fetch c2 in r2;
exit when c2%notfound;
/* new record */
insert into t1
values (t1_seq.nextval, t2.value)
returning t1.id into new_id;
/* update existing record with id*/
update t2
set id = new_id
where current of c2;
end loop;
commit;
end;
/
此解决方案是逐行排列的#34;这是确保将新T1.ID
应用于T2
中的正确行的最简单方法。如果T1
很小并且/或者这是一次开球练习,那可能就好了。但如果表现是一个问题,那么可以使用调音。
答案 1 :(得分:1)
如果在表2中有很多行,我建议您使用bulk collect
。
它将帮助您提高数据库的性能。像这样:
declare
type type_table2 is table of table2%rowtype index by binary_integer;
vt_table2 type_table2;
cursor cur_table2 is select * from table2;
begin
open cur_table2;
loop
fetch cur_table2 bulk collect into vt_table2 limit 500;
for i in 1..vt_table2.count loop
begin
insert into table1
values(i, vt.table2(i).value);
update table2
set id = i
where current of cur_table2;
exception when other then
excp := SQLERRM;
dbms_output.put_line('Error:'||excp);
end;
end loop;
exit when cur_table%notfound;
end loop;
close cur_table2;
commit;
exception when other then
excp := SQLERRM;
dbms_output.put_line('Error:'||excp);
end;