如何将值从一个表插入另一个表然后更新原始表?

时间:2017-05-03 10:54:36

标签: oracle plsql

使用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_2
ID    VALUE
-----------
1     Val 1
2     Val 2
3     Val 3

2 个答案:

答案 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;