如何调用具有 IN/OUT 参数并通过 DB Link 返回 BLOB 的 Oracle PL/SQL 函数

Posted

技术标签:

【中文标题】如何调用具有 IN/OUT 参数并通过 DB Link 返回 BLOB 的 Oracle PL/SQL 函数【英文标题】:How to call Oracle PL/SQL Function which has IN/OUT argument and returns BLOB through DB Link 【发布时间】:2016-04-25 12:02:15 【问题描述】:

我有一个 Oracle PL/SQL 函数(让它命名为 GetRemoteBlob),它驻留在远程数据库的一个包中,接受一个 IN/OUT 参数并返回 BLOB。对于这个远程数据库,我有一个 dblink。我不能修改远程数据库上的任何东西,也不能直接使用这些表。

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

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

如果不使用Java无法调用,Java实现应该如何,允许我传递IN/OUT参数并在远程调用后获取OUT值?

提前感谢您的关注和帮助。

【问题讨论】:

你不能……至少不能直接。 Blob 对象不能通过 DB 链接返回。您必须先将 Blob 转换为其他东西,然后才能返回它。虽然gumpx.wordpress.com/2014/06/09/… 可能会提供一些有用的指针或this asktom article 感谢 xQbert 的评论。我知道这些信息,这就是为什么我明确指定我不允许直接使用远程数据库中的表......如果我理解正确,你的意思是,除了 Java 解决方案之外,还有没有其他方法可以从远程数据库中检索 BLOB? 【参考方案1】:

我决定回答这个问题,因为其他人可能会检查它,是的,有一种解决方案,但正如已经评论的那样,你不能直接从 dblink 获取 blob。

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

创建或替换函数 GETBLOBVIADBLINK ( varchar2 中的 dblnk , varchar2 中的 tbl ,col in varchar2 ,rwid 在 urowid) 返回 blob 是 retval 斑点; tmpraw 原始(2000); tmplen 号码; tmpchk 号; chksize 编号; 开始 --预设变量 chksize:=2000; dbms_lob.createtemporary (retval,true); 立即执行'select dbms_lob.getlength@'||dblnk||' ('||col||') 来自'||tbl||'@'||dblnk||'其中 rowid=:rwid' 使用 rwid 进入 tmlen; -- 预计算 tmpchk:=floor(nvl(tmplen, 0)/chksize); -- 应用第一块 对于我在 0 .. tmpchk-1 环形 立即执行 'select dbms_lob.substr@'||dblnk||'('||col||','||chksize||','||((i*chksize)+1)||') from ' ||tbl||'@'||dblnk||'其中 rowid=:rwid' 使用 rwid 进入 tmpraw; dbms_lob.append(retval,tmpraw); 结束循环; -- 应用最后一个条目 如果 (tmplen-(tmpchk*chksize)) > 0 那么 立即执行'select dbms_lob.substr@'||dblnk||'('||col||','||(tmplen-(tmpchk*chksize))||','||((tmpchk*chksize)+ 1)||') 来自 '||tbl||'@'||dblnk||'其中 rowid=:rwid' 使用 rwid 进入 tmpraw; dbms_lob.append(retval,tmpraw); 万一; 返回 retval; 结尾;

来自link 的信用是 Gumpx 的,我刚刚将其设为 nullsafe

【讨论】:

感谢 CsBalazsHungary 采用这种方法。我还查看了您发布的链接中的文章......这些解决方案(尤其是第 1 版)看起来确实很有前途。不幸的是,他们没有解决我的问题——我不允许“直接”使用远程数据库中的表(“立即执行......”就是这样做的)......我目前正在使用基于 Java 的解决方案。

以上是关于如何调用具有 IN/OUT 参数并通过 DB Link 返回 BLOB 的 Oracle PL/SQL 函数的主要内容,如果未能解决你的问题,请参考以下文章

oracle中in和out用法

MySQL 存储过程传参之in, out, inout 参数用法

如何解决 Kettle 中的这个 in/out mysql 参数错误?

包装采用 char** [in/out] 的 C 函数调用,以在 cython 中返回 python 列表

GDB:如何在调试期间调用具有修改参数的函数

oracle存储过程,IN OUT 类型的参数怎么传参数