异构数据库分布式事务的ORA-02025错误

对于ORACLE参与的异构数据库的分布式事务,ORACLE允许 INSERT INTO 本地表 SELECT * FROM 远程,
但是不允许INSERT INTO 远程表 SELECT * FROM 本地表:
否则就会引发:

ORA-02025: all tables in the SQL statement must be at the remote database.
 
如下一个简单的例子。
(远程库是一个DB2V9.5的数据库。目标数据库是ORACLE 10.2.0.5的数据库。)
 
首先在远程DB2中创建测试表T。
 

点击(此处)折叠或打开

  1. db2 => create table t(id int)
  2. DB20000I SQL命令成功完成。
  3. db2 => insert into t values(1)
  4. DB20000I SQL命令成功完成。
  5. db2 => select * from t

  6. ID
  7. -----------

  8.           1

  9.   1 条记录已选择。

  10. db2 => commit
  11. DB20000I SQL命令成功完成。
  12. db2 =>
我已经配置好了透明网关,并且在ORACLE中建立了DBLINK DB2DB指向远程数据库。
数据也能从正常查询到。

点击(此处)折叠或打开

  1. SQL> SELECT * FROM T@DB2DB
  2.   2 ;

  3.         ID
  4. ----------

  5.          1

也可以将DB2中的数据插入到ORACLE中,如下:


点击(此处)折叠或打开

  1. SQL> CREATE TABLE ORACLE_T (ID INT);

  2. 表已创建。

  3. SQL> INSERT INTO ORACLE_T SELECT * FROM T@DB2DB;

  4. 已创建 1 行。

  5. SQL> COMMIT;

  6. 提交完成。

  7. SQL> SELECT * FROM ORACLE_T;

  8.         ID
  9. ----------

  10.          1

  11. SQL>

但是不允许如下的形式将ORACLE的数据插入到DB2中:

点击(此处)折叠或打开

  1. SQL> INSERT INTO T@DB2DB SELECT * FROM ORACLE_T;
  2. INSERT INTO T@DB2DB SELECT * FROM ORACLE_T
  3.                            *
  4. 第 1 行出现错误:
  5. ORA-02025: all tables in the SQL statement must be at the remote database
如下的方法是可以的:

点击(此处)折叠或打开

  1. SQL> INSERT INTO T@DB2DB VALUES(2);

  2. 已创建 1 行。

  3. SQL> COMMIT;

  4. 提交完成。

  5. SQL> SELECT * FROM T@DB2DB;

  6.         ID
  7. ----------

  8.          1
  9.          2

  10. db2端:

  11. db2 => select * from t

  12. ID
  13. -----------

  14.           1
  15.           2

  16.   2 条记录已选择。

  17. db2 =>

因此可以采用游标循环的方法来解决这个问题:

点击(此处)折叠或打开

  1. SQL> SELECT * FROM ORACLE_T;

  2.         ID
  3. ----------

  4.          1

  5. SQL> DELETE FROM ORACLE_T;

  6. 已删除 1 行。

  7. SQL> DELETE FROM T@DB2DB;

  8. 已删除2行。

  9. SQL> COMMIT;

  10. 提交完成。

  11. SQL> INSERT INTO ORACLE_T SELECT ROWNUM FROM DUAL
  12.   2 CONNECT BY LEVEL < =5;

  13. 已创建5行。

  14. SQL> COMMIT;

  15. 提交完成。

  16. SQL> SELECT * FROM ORACLE_T;

  17.         ID
  18. ----------

  19.          1
  20.          2
  21.          3
  22.          4
  23.          5

  24. SQL> SELECT * FROM T@DB2DB;

  25. 未选定行




  26. SQL> BEGIN
  27.   2 FOR X IN (SELECT ID FROM ORACLE_T) LOOP
  28.   3 INSERT INTO T@DB2DB VALUES(X.ID);
  29.   4 END LOOP;
  30.   5 COMMIT;
  31.   6 END;
  32.   7 /

  33. PL/SQL 过程已成功完成。

  34. SQL> SELECT * FROM T@DB2DB;

  35.         ID
  36. ----------

  37.          1
  38.          2
  39.          3
  40.          4
  41.          5
注意:远程表不支持FORALL的批量插入。

点击(此处)折叠或打开

  1. SQL> delete from t@db2db;

  2. 已删除5行。

  3. SQL> commit;

  4. 提交完成。

  5. SQL> declare
  6.   2 cursor mycursor is select id from oracle_t;
  7.   3 type id_table_type is table of number index by binary_integer;
  8.   4 id_table id_table_type;
  9.   5 i int;
  10.   6 begin
  11.   7 open mycursor;
  12.   8 fetch mycursor bulk collect into id_table ;
  13.   9 close mycursor;
  14.  10 forall i in id_table.first..id_table.last
  15.  11 insert into t@db2db values(id_table(i));
  16.  12 commit;
  17.  13 end;
  18.  14 /
  19.   forall i in id_table.first..id_table.last
  20.   *
  21. 第 10 行出现错误:
  22. ORA-06550: line 10, column 3:
  23. PLS-00739: FORALL INSERT/UPDATE/DELETE not supported on remote tables
除此之外,SQLPLUS的COPY命令也可以解决这个问题。

点击(此处)折叠或打开

  1. SQL> COPY FROM report/report@reportdb insert t@db2db using select
  2.  id from oracle_t

  3. 数组提取/绑定大小为 15。(数组大小为 15)
  4. 将在完成时提交。(提交的副本为 0)
  5. 最大 long 大小为 80。(long 为 80)
  6. 5 行选自 report@reportdb。
  7.    5 行已插入 T@DB2DB。
  8.    5 行已提交至 T@DB2DB (位于 DEFAULT HOST 连接)

  9. SQL> select * from t@db2db;

  10.         ID
  11. ----------

  12.          1
  13.          2
  14.          3
  15.          4
  16.          5
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值