데이터베이스 링크를 통해 사용되는 경우 오라클에 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
의 경우는 11g에 확인 후 내가 실현이 구현 제한했다이 보여주기 위해 간단한 예입니다 .
for i in t_test.first .. t_test.last loop
insert into [email protected]
values t_test(i);
end loop;
하지만, 오히려 가능한 모든 경우에 하나의 삽입에 그것을 아래로 유지하는 것이 라운드
ERROR at line 18: ORA-06550: line 18, column 4: PLS-00739: FORALL INSERT/UPDATE/DELETE not supported on remote tables
진짜로 확실한 방법은에 forall ..
을 변경하는 것입니다. Tom Kyte suggests the use of a global temporary table. 데이터를 GTT에 삽입 한 다음 DB 링크를 통해 삽입하면 이미 사용자 정의 유형에있는 데이터 집합에 대한 엄청난 과잉 상태 인 것처럼 보입니다.
이 예제를 명확히하기 위해 실제로 일어나는 것과 비교하여 극히입니다. 우리가 간단한 insert into
을 할 수있는 방법이 없으며 GTT에서 모든 작업을 수행 할 수있는 방법이 없습니다. 코드의 대부분은 사용자 정의 유형으로 수행해야합니다.
DMLy가 더 간단하거나 더 적은 방법이 있습니까?
GTT 이상을 시도해 보셨습니까? 11g의 성능을 비교하십시오. 과도기는 아니지만 날짜를 이동하는 빠른 방법이라고 생각합니다. –
아니요. 시도하지 않았습니다. 다른 옵션이 없다면 분명히 알 수 있습니다. 기억에서 무언가를 취하는 것이 이상하게 보입니다. 다른 메모리로 이동 한 다음 DML을 수행하십시오. 좀 더 단순한 솔루션을 원했습니다. 존재하는 경우. – Ben
조금만 생각해보십시오. GTT 부분은 순수한 SQL이며 빠른 것입니다 (dblink 패널티). 느린 것은 배열과 함께 ps/sql 부분입니다 ... –