>我需要将所有记录从表A迁移到表B。目前我只是使用以下语句:
INSERT INTO table1 (id, name, description) SELECT id, name, descriptionOld
FROM table2;
COMMIT;
问题是,如果有大量记录,则临时表空间可能没有足够的空间来处理此语句。出于这个原因,我想知道是否有任何方法仍然通过当时提交 1000 条记录的循环来保持此语句。
谢谢!
对于庞大的数据处理,必须查看context
SQL
引擎和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;
/
假设你有这些表:
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 c
和d
。这是一种不是在单个语句中复制记录,而是在给定行数的块中复制记录的方法。
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;
如果遵循此方法,则当某些记录(但不是全部)已被复制(并提交)时,可能会收到错误,因此您必须根据需要考虑处理这种情况的最佳方法。