使用INSERT INTO x SELECT FROM y语句迁移记录并循环

时间:2017-01-02 15:02:29

标签: oracle plsql

我需要将所有记录从 tableA 迁移到 tableB 。目前我只是使用以下声明:

INSERT INTO table1 (id, name, description) SELECT id, name, descriptionOld
FROM table2;
COMMIT;

问题是如果有大量记录,临时表空间可能没有足够的空间来处理此语句。出于这个原因,我想知道是否有任何方法仍然可以通过一个循环提交此语句,例如,当时提交1000条记录

谢谢!

2 个答案:

答案 0 :(得分:1)

假设你有这些表:

create table sourceTab( a number, b number, c number);
create table targetTab( a number, b number, c number, d number);

并且您希望将记录从sourceTab复制到targetTab,同时填充tagret表的coumns cd以及列{{1}的值在源头。 这是一种复制记录的方法,不是在单个语句中,而是在给定行数的块中。

C

如果您遵循这种方法,当某些记录(但不是全部)已被复制(并已提交)时,您可能会收到错误,因此您必须根据需要考虑处理此案例的最佳方法。 / p>

答案 1 :(得分:1)

对于大量数据处理,必须查看contextSQL引擎之间的PLSQL切换。一种方法可以允许从tableA插入到tableB并在插入完成后处理错误记录。您创建与目标表相同的错误tableC以处理错误记录。因此,一旦完成从tableA复制数据,您就可以查看错误记录,并在进行更正后直接执行并插入tableB。请参阅下文,了解如何做到这一点。

declare
    cursor C is
    select *
      from table_a;

    type array is table of c%rowtype;
    l_data array;

    dml_errors EXCEPTION;
    PRAGMA exception_init(dml_errors, -24381);

    l_errors number;  
    l_idx    number;
begin
    open c;
    loop
        --Limit 100 will give optimal number of context switching and best perfomance
        fetch c bulk collect into l_data limit 100; 
        begin
            forall i in 1 .. l_data.count SAVE EXCEPTIONS
                insert into table_b 
                values l_data(i);
        exception
            when DML_ERRORS then
                l_errors := sql%bulk_exceptions.count;
                for i in 1 .. l_errors
                loop                    
                    l_idx   := sql%bulk_exceptions(i).error_index;
                   --Insertnig error records to a error table_c so that later on these records can be handled. 
                   insert  into table_c
                    values l_data(l_idx);
                end loop;
              commit;
        end;
        exit when c%notfound;
    end loop;
    close c;
 commit;
end;
/