ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 执行远端DBMS_LOB包中过程

执行远端DBMS_LOB包中过程

原创 Linux操作系统 作者:yangtingkun 时间:2010-06-12 23:58:43 0 删除 编辑

简单描述执行远端的DBMS_LOB包的一些问题。

 

 

由于LOB的定位符无法跨数据库链使用,因此访问远端LOB对象的时候,需要调用远端的DBMS_LOB包中的过程,但是测试发现,即使调用远端的DBMS_LOB包中的过程,仍然可能出现问题。

SQL> CREATE TABLE T_LOB (ID NUMBER, CONTENTS CLOB);

表已创建。

SQL> DECLARE
  2     V_LOB CLOB;
  3  BEGIN
  4     INSERT INTO T_LOB
  5     VALUES (1, EMPTY_CLOB())
  6     RETURN  CONTENTS INTO V_LOB;
  7     FOR I IN 1..100 LOOP
  8        DBMS_LOB.WRITEAPPEND(V_LOB, 32767, LPAD('A', 32767, 'A'));
  9     END LOOP;
 10  END;
 11  /

PL/SQL 过程已成功完成。

SQL> COMMIT;

提交完成。

SQL> SELECT DBMS_LOB.GETLENGTH(CONTENTS) FROM T_LOB;

DBMS_LOB.GETLENGTH(CONTENTS)
----------------------------
                     3276700

SQL> SELECT * FROM V$VERSION;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE    10.2.0.3.0      Production
TNS for Linux: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production

SQL> SELECT * FROM GLOBAL_NAME;

GLOBAL_NAME
----------------------------------------------------------------------------
TESTZJ

如果在远端数据库中,通过数据库链获取这个LOB字段的长度,直接通过DBMS_LOB.GETLENGTH肯定是行不通的:

SQL> SELECT * FROM GLOBAL_NAME;

GLOBAL_NAME
----------------------------------------------------------------------------------
TEST08

SQL> SELECT * FROM V$VERSION;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE    10.2.0.3.0      Production
TNS for Linux: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production

SQL> CREATE DATABASE LINK TESTZJ
  2  CONNECT TO TEST
  3  IDENTIFIED BY TEST
  4  USING '172.25.13.231/TESTZJ';

Database link created.

SQL> SELECT COUNT(*) FROM T_LOB@TESTZJ;

  COUNT(*)
----------
         1

SQL> SELECT DBMS_LOB.GETLENGTH(CONTENTS) FROM T_LOB@TESTZJ;
SELECT DBMS_LOB.GETLENGTH(CONTENTS) FROM T_LOB@TESTZJ
                          *
ERROR at line 1:
ORA-22992: cannot use LOB locators selected from remote tables

尝试调用远端的DBMS_LOB包,但是仍然会导致错误的产生:

SQL> SELECT DBMS_LOB.GETLENGTH@TESTZJ(CONTENTS) FROM T_LOB@TESTZJ;
SELECT DBMS_LOB.GETLENGTH@TESTZJ(CONTENTS) FROM T_LOB@TESTZJ
                                 *
ERROR at line 1:
ORA-22992: cannot use LOB locators selected from remote tables

按道理来说,虽然T_LOB是远端对象,但是DBMS_LOB调用的也是远端过程,LOB定位符的使用并没有跨越数据库,因此应该是可以得到结果的。

在11.2中,Oracle已经可以利用这种方法来进行访问了:

SQL> SELECT * FROM GLOBAL_NAME;

GLOBAL_NAME
---------------------------------------------------------------------------------
TEST112

SQL> SELECT * FROM V$VERSION;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

SQL> CREATE DATABASE LINK TESTZJ
  2  CONNECT TO TEST
  3  IDENTIFIED BY TEST
  4  USING '172.25.13.231/TESTZJ';

数据库链接已创建。

SQL> SELECT COUNT(*) FROM T_LOB@TESTZJ;

  COUNT(*)
----------
         1

SQL> SELECT DBMS_LOB.GETLENGTH@TESTZJ(CONTENTS) FROM T_LOB@TESTZJ;

DBMS_LOB.GETLENGTH@TESTZJ(CONTENTS)
-----------------------------------
                            3276700

SQL> SELECT LENGTH(CONTENTS) FROM T_LOB@TESTZJ;

LENGTH(CONTENTS)
----------------
         3276700

在11g中,甚至可以通过LENGTH函数直接获取远端LOB的长度。

虽然10.2中不能通过远端的DBMS_LOB直接访问表中的LOB,但是还是可以利用这个包处理函数返回的LOB。

对于低版本的情况,为了可以使用远端的DBMS_LOB包,需要在远端站点建立一个函数,返回LOB对象:

SQL> SELECT * FROM GLOBAL_NAME;

GLOBAL_NAME
---------------------------------------------------------------------------------
TESTZJ

SQL> CREATE OR REPLACE FUNCTION F_LOB (P_ID IN NUMBER)
  2  RETURN CLOB AS
  3     V_LOB CLOB;
  4  BEGIN
  5     SELECT CONTENTS
  6     INTO V_LOB
  7        FROM T_LOB
  8     WHERE ID = P_ID;
  9     RETURN V_LOB;
 10  END;
 11  /

函数已创建。

下面通过调用F_LOB来处理LOB的长度:

SQL> SELECT * FROM GLOBAL_NAME;

GLOBAL_NAME
-------------------------------------------------------------------------
TEST08

SQL> SELECT DBMS_LOB.GETLENGTH@TESTZJ(F_LOB@TESTZJ(1)) FROM T_LOB@TESTZJ;

DBMS_LOB.GETLENGTH@TESTZJ(F_LOB@TESTZJ(1))
------------------------------------------
                                   3276700

SQL> SELECT LENGTH(F_LOB@TESTZJ(1)) FROM T_LOB@TESTZJ;

LENGTH(F_LOB@TESTZJ(1))
-----------------------
                3276700

通过在远端先调用F_LOB返回CLOB后,就可以通过远端的DBMS_LOB.GETLENGTH来获取长度了。

在调用远端F_LOB并返回CLOB后,甚至可以直接通过LENGTH来获取LOB字段的长度。

从这一点上看,LENGTH和DBMS_LOB.GETLENGTH要拥有更多的优势。

 

 

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4227/viewspace-665128/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
暂无介绍

注册时间:2007-12-29

  • 博文量
    1964
  • 访问量
    11077275