简体   繁体   中英

How to call Oracle PL/SQL Function which has IN/OUT argument and returns BLOB through DB Link

I have an Oracle PL/SQL function (let name it GetRemoteBlob), which resides in a package on a remote database, takes one IN/OUT argument and returns BLOB. To this remote database I've a dblink. I'm not allowed to modify anything on the remote database, nor I'm allowed to use the tables directly.

One possible usage of this function is to use Java code to transfer the BLOB over to the local database. The drawback of this solution is, local databases without Java installed (like Oracle XE database) cannot use this functionality.

My questions are like these: Is it possible to call that function GetRemoteBlob through the dblink, without to use Java (or external C) code?

If calling without Java is not possible, how should be the Java implementation, that allows me to pass the IN/OUT argument and to get the OUT value after the remote call?

Thanks you in advance for your attention and your help.

I decided to answer this question because others might check it out and yes, there is a kind of solution, but as it is commented already, directly you can't get blobs from dblink.

However you can make a function in oracle which is capable to read blobs, I never tested the limitations, but for me it worked for couple of kilobytes and megabytes blobs, and it is fairly quick.

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 dbms_lob.getlength@'||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 dbms_lob.substr@'||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 dbms_lob.substr@'||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;

credit is Gumpx's from this link , I just made it nullsafe

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM