【问题标题】:how to get row which uses bulk insert and forall to update base table如何获取使用批量插入和 forall 更新基表的行
【发布时间】:2013-03-27 11:35:14
【问题描述】:

我有一个没有主键的临时表(大约 760k 行)。我正在尝试使用批量收集和 forall 将此临时表中的行插入到我的主表中(也使用保存异常来捕获被拒绝的行),我已经成功地做到了这一点。但是我需要跟踪被拒绝和成功移动的行(我想要做的是将临时表的状态列更新为“E”表示错误,M 表示成功迁移) 这是我的程序:

代码sn-p

desc temp_table:
col1 varchar2(30);
col2 varchar2(30);
col3 number;
col4 number;
status varchar2(1);

create or replace procedure mov_to_main_table
as
loop_count number default 0;
error_row_no number default 0;
sql_stmt varchar2(500);
cursor c_data is
   select * from temp_table,a
    where temp_table.col1=a.col;

TYPE t_bulk_collect_tab IS TABLE OF c_data%ROWTYPE;

l_tab t_bulk_collect_tab;
l_inserted t_bulk_collect_tab; 

BEGIN

OPEN c_data;
LOOP
FETCH c_data
BULK COLLECT INTO l_tab LIMIT 1000;

EXIT WHEN l_tab.count = 0;
BEGIN

FORALL i IN 1..l_tab.count  save exceptions
insert into main_table(col1,col2,col3)
values(l_tab(i).col1,l_tab(i).col2,l_tab(i),col3);

EXCEPTION
when others then
bulk_error_count := sql%bulk_exceptions.count;
--dbms_output.put_line('number of error rows :'||bulk_error_count );
for i in 1..bulk_error_count
loop
error_row_no := to_number(SQL%BULK_EXCEPTIONS(i).ERROR_INDEX)+100*loop_count;
sql_stmt := 'update  temp_table set status=''E'' where rowid in (select rowid from     temp_table where rownum <=:1 minus select rowid from temp_table where rownum<:2)';
execute immediate sql_stmt using error_row_no,error_row_no;

end loop;


end;

在上面的代码中,我将进入异常部分的行更新为“E” 但是对于成功插入的行,我无法更新状态, 主要是我需要捕捉那个 rownum 或 rowid 来更新我无法从所有人那里得到 如何更新成功移动的行? 请帮帮我 提前谢谢..

【问题讨论】:

    标签: oracle plsql


    【解决方案1】:

    你的方法很聪明,但有一些事情不能正常工作:

    1. 首先,这里不需要动态 SQL,直接删除即可。
    2. 您仍然可以访问异常块中的l_tab 嵌套表,因此很容易选择相关的idrowid
    3. 最后,这不是在 Oracle 中使用分页查询的方式,请参阅 examples on SO

    我的建议是在获取其余数据的同时获取 rowid:

    CURSOR c_data IS
       SELECT temp_table.*, a.*, temp_table.rowid rid 
         FROM temp_table, a 
        WHERE temp_table.col1 = a.col;
    

    然后在异常块中你可以找到并更新有问题的行:

    EXCEPTION
       WHEN OTHERS THEN
          bulk_error_count := SQL%bulk_exceptions.count;
          --dbms_output.put_line('number of error rows :'||bulk_error_count );
          FOR i IN 1 .. bulk_error_count LOOP
             UPDATE temp_table
                SET status = 'E'
              WHERE rowid = l_tab(SQL%BULK_EXCEPTIONS(i).error_index).rid);  
          END LOOP;
    END;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-19
      • 2021-11-25
      • 1970-01-01
      • 2014-02-16
      • 1970-01-01
      • 1970-01-01
      • 2011-09-29
      相关资源
      最近更新 更多