データベースリンク上で使用すると、Oracle上でのforall .. insert
の使用を禁止する実装制限があるように見えます。非常にが紛らわしい、これが次のエラーで9iのに失敗し データベースリンクを介したバルク挿入の制限の克服
connect schema/[email protected]
create table tmp_ben_test (
a number
, b number
, c date
, constraint pk_tmp_ben_test primary key (a, b)
);
Table created.
connect schema/[email protected]
Connected.
declare
type r_test is record (a number, b number, c date);
type t__test is table of r_test index by binary_integer;
t_test t__test;
cursor c_test is
select 1, level, sysdate
from dual
connect by level <= 10
;
begin
open c_test;
fetch c_test bulk collect into t_test;
forall i in t_test.first .. t_test.last
insert into [email protected]
values t_test(i)
;
close c_test;
end;
/
:
ERROR at line 1: ORA-01400: cannot insert NULL into ("SCHEMA"."TMP_BEN_TEST"."A") ORA-02063: preceding line from DB1 ORA-06512: at line 18
た場合のみ11グラムでチェックした後、私が実現した、これは実装上の制約だったこれは、実証する簡単な例であります。
ERROR at line 18: ORA-06550: line 18, column 4: PLS-00739: FORALL INSERT/UPDATE/DELETE not supported on remote tables
このラウンドは本当に明白な方法はにforall ..
を変更することです:
for i in t_test.first .. t_test.last loop
insert into [email protected]
values t_test(i);
end loop;
が、すべての可能性であれば、私はむしろ、単一のインサートにそれを維持したいです。 Tom Kyte suggests the use of a global temporary table。 GTTにデータを挿入した後、DBリンクを介してデータを挿入すると、既にユーザー定義型のデータセットに対する大過剰なオーバーヒルのように思えます。
この例を明確にすると、実際に起こっていることと比べて、極端にはです。 insert into
を簡単に実行できる方法はなく、すべての操作をGTTで実行する方法はありません。コードの大部分はユーザー定義型で行う必要があります。
この制限を回避する別のDMLyがありますか?
あなたはGTT ideeaを試しましたか? 11gの性能を比較してください。私は過労ではないが、日付を移動するための迅速な方法だと思う。 –
いいえ私はそれを試していない。私は明らかに他の選択肢がないかどうかはわかります。メモリから何かを取るのはちょっと変わったようです。別のメモリに移動してDMLを実行します。よりシンプルなソリューションを望んでいました。存在する場合。 – Ben
少し考えてみてください。 GTTの部分は純粋なSQLであり、速くなります(dblinkのペナルティ)。遅いのは、配列を持つps/sqlの部分です... –