2016-04-25 23 views
3

我有一个驻留在远程数据库的包中的Oracle PL/SQL函数(将其命名为GetRemoteBlob)需要一个IN/OUT参数并返回BLOB。对于这个远程数据库,我有一个dblink。我不允许修改远程数据库上的任何内容,也不允许我直接使用这些表。如何调用具有IN/OUT参数并通过DB返回BLOB的Oracle PL/SQL函数

此函数的一种可能用法是使用Java代码将BLOB传输到本地数据库。此解决方案的缺点是,未安装Java的本地数据库(如Oracle XE数据库)无法使用此功能。

我的问题是这样的: 是否有可能通过dblink调用该函数GetRemoteBlob,而不使用Java(或外部C)代码?

如果不使用Java进行调用是不可能的,那么Java实现应该如何实现呢?它允许我通过IN/OUT参数并在远程调用后获取OUT值?

非常感谢您的关注和帮助。

+3

你不能......至少不直接。 Blob对象不能通过DB链接返回。在返回之前,你必须将Blob投到其他东西上。虽然https://gumpx.wordpress.com/2014/06/09/oracle-database-select-blob-via-db-link/可能会提供一些有用的指针或[本问答文章](https://asktom.oracle .com/pls/apex/f?p = 100:11:0 :::: P11_QUESTION_ID:52297289480186) – xQbert

+0

感谢xQbert对此评论。我知道这些信息,这就是我明确指定我不允许直接使用远程数据库中的表的原因......如果我理解正确,那么除了Java解决方案之外,还有没有其他方式从远程数据库中检索BLOB? – Ramanagom

回答

0

我决定回答这个问题,因为别人可能会检查出来,是的,有一种解决方案,但由于它已被评论,所以直接不能从dblink获取blob。

但是你可以在oracle中创建一个能够读取blob的函数,我从来没有测试过这个限制,但是对于我来说,它适用于几千字节和兆字节的blob,而且速度相当快。

 
create or replace function GETBLOBVIADBLINK 
(dblnk in varchar2 
    ,tbl in varchar2 
    ,col in varchar2 
    ,rwid in urowid) 
return blob 
is 
    retval blob; 
    tmpraw raw(2000); 
    tmplen number; 
    tmpchk number; 
    chksize number; 
begin 
    --preset vars 
    chksize:=2000; 
    dbms_lob.createtemporary (retval,true); 
    execute immediate 'select [email protected]'||dblnk||' ('||col||') from '||tbl||'@'||dblnk||' where rowid=:rwid' into tmplen using rwid; 

    -- precalc 
    tmpchk:=floor(nvl(tmplen, 0)/chksize); 

    -- applicate frist chunks 
    for i in 0 .. tmpchk-1 
    loop 
    execute immediate 'select [email protected]'||dblnk||'('||col||','||chksize||','||((i*chksize)+1)||') from '||tbl||'@'||dblnk||' where rowid=:rwid' into tmpraw using rwid; 
    dbms_lob.append(retval,tmpraw); 
    end loop; 

    -- applicate last entry 
    if (tmplen-(tmpchk*chksize)) > 0 then 
    execute immediate 'select [email protected]'||dblnk||'('||col||','||(tmplen-(tmpchk*chksize))||','||((tmpchk*chksize)+1)||') from '||tbl||'@'||dblnk||' where rowid=:rwid' into tmpraw using rwid; 
    dbms_lob.append(retval,tmpraw); 
    end if; 
    return retval; 
end; 

信用Gumpx的从这个link,我只是做它nullsafe

+0

感谢CsBalazsHungary提供这种方法。我也看过您发布的链接中的文章......这些解决方案(特别是版本1)确实看起来非常有前景。不幸的是,它们不能解决我的问题 - 我不允许直接使用远程数据库中的表(“立即执行......”),我正在使用基于Java的解决方案。 – Ramanagom

相关问题