克服通过数据库链接进行批量插入的限制 [英] Overcoming the restriction on bulk inserts over a database link

查看:220
本文介绍了克服通过数据库链接进行批量插入的限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当在数据库链接上使用时,似乎存在禁止在Oracle上使用forall .. insert的实现限制.这是一个简单的示例来演示:

It appears as though there's an implementation restriction that forbids the use of forall .. insert on Oracle, when used over a database link. This is a simple example to demonstrate:

connect schema/password@db1

create table tmp_ben_test (
   a number
 , b number
 , c date
 , constraint pk_tmp_ben_test primary key (a, b)
    );

Table created.

connect schema/password@db2
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 tmp_ben_test@db1
     values t_test(i)
            ;

   close c_test;

end;
/

非常令人困惑的是,它在9i中失败,并出现以下错误:

Very confusingly this fails in 9i with the following error:

在第1行出现错误:ORA-01400:无法将NULL插入 ("SCHEMA"."TMP_BEN_TEST"."A")ORA-02063:DB1的前一行 ORA-06512:在第18行

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后才意识到这是实施限制.

If was only after checking in 11g that I realised this was an implementation restriction.

第18行出现错误:ORA-06550:第18行第4列:PLS-00739:全部 远程表不支持INSERT/UPDATE/DELETE

ERROR at line 18: ORA-06550: line 18, column 4: PLS-00739: FORALL INSERT/UPDATE/DELETE not supported on remote tables

解决这个问题的最明显方法是将forall ..更改为:

The really obvious way round this is to change forall .. to:

for i in t_test.first .. t_test.last loop
    insert into tmp_ben_test@db1
    values t_test(i);
end loop;

但是,如果可能的话,我宁愿将其保留为单个插入. 汤姆·凯特(Tom Kyte)建议使用全局临时表.将数据插入GTT,然后通过DB链接,对于已经属于用户定义类型的一组数据来说似乎是过大的杀伤力.

but, I'd rather keep it down to a single insert if at all possible. Tom Kyte suggests the use of a global temporary table. Inserting the data into a GTT and then over a DB link seems like massive overkill for a set of data that is already in a user-defined type.

极端地只是简化了这个示例.我们不可能做一个简单的insert into,也不可能在GTT上完成所有操作.代码的大部分必须以用户定义的类型完成.

Just to clarify this example is extremely simplistic compared to what is actually happening. There is no way we will be able to do a simple insert into and there is no way all the operations could be done on a GTT. Large parts of the code have to be done in user-defined type.

是否有另一种或更简单或更简单的DMLy可以解决此限制?

Is there another, simpler or less DMLy, way around this restriction?

推荐答案

您在远程数据库上面临哪些限制?如果可以在其中创建对象,则有一个解决方法:在远程数据库上创建集合类型,并执行一个将集合作为参数并执行FORALL语句的过程.

What restrictions do you face on the remote database? If you can create objects there you have a workaround: on the remote database create the collection type and a procedure which takes the collection as a parameter and executes the FORALL statement.

这篇关于克服通过数据库链接进行批量插入的限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆