使用插入到 x 从 y 中选择语句和循环来迁移记录



>我需要将所有记录从表A迁移到表B。目前我只是使用以下语句:

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

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

谢谢!

对于庞大的数据处理,必须查看context SQL引擎和PLSQL引擎之间的切换。一种方法是让插入从tableAtableB,并在插入完成后处理错误记录。创建与目标表相同的错误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;
/

假设你有这些表:

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

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

DECLARE
    CURSOR sourceCursor IS SELECT a, b, c, c as d FROM sourceTab;
    TYPE        tSourceTabType IS TABLE OF sourceCursor%ROWTYPE;   
    vSourceTab  tSourceTabType;
    vLimit      number := 10;   /* here you decide how many rows you insert in one shot */
BEGIN   
    OPEN sourceCursor;
    LOOP
        FETCH sourceCursor 
            BULK COLLECT INTO vSourceTab LIMIT vLimit;
        forall i in vSourceTab.first .. vSourceTab.last
            insert into targetTab values vSourceTab(i);
        commit;
        EXIT WHEN vSourceTab.COUNT < vLimit;
   END LOOP;
   CLOSE sourceCursor;
END;

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

相关内容

  • 没有找到相关文章

最新更新