基于Oracle Forms Builder 海洋地形信息系统设计与实现(三)

来源:互联网 发布:化妆品的网络调查 编辑:程序博客网 时间:2024/04/29 09:23
OracleBlob大对象的上传和下载

Form Builder 上传和下载大对象Blob是一个难点,本文将详细讲述。

首先创建一个数据表demo(iid number,theblob blob),然后建立以这个数据表为数据块的表单。

一、利用Form Builder内建程序上传和下载图片

表中已有一条记录,有代码但没有图片。

读入相片

read_image

declare

       file_namevarchar2(80);

begin

       set_block_property('demo',default_where,'iid='||:block14.code);

       go_block('demo');

       execute_query;

       file_name:='c:\temp\123.jpg';

       read_image_file(file_name,'jpg','demo.theblob');

end;

下载相片

declare

       file_namevarchar2(80);

begin

       set_block_property('demo',default_where,'iid='||:block14.code);

       go_block('demo');

       execute_query;

       file_name:='c:\temp\output.jpg';

       write_image_file(file_name,'jpg','demo.theblob',NO_COMPRESSION,original_depth);

end;

二、通过服务器端上传大对象文件

子程序包括服务器端子程序和客户端子程序两种类型,其中服务器端子程序是指存放在数据库中的过程、函数和包,而客户端子程序则指存放在pl/sql库中的过程、函数和包。

创建目录:

CREATE OR REPLACE DIRECTORY my_files AS ‘C;\temp’;

上传文件过程:

create or replace procedure uploadblobbybfile

as

    l_blob           blob;

    l_bfile           bfile;

  begin

    l_bfile := bfilename ('MY_FILES','006.jpg');

    insert into demo (iid, theblob)

    values (8, empty_blob())

    returning theblob

    into l_blob;

    dbms_lob.fileopen (l_bfile);

    dbms_lob.loadfromfile

        (l_blob,

         l_bfile,

         dbms_lob.getlength (l_bfile));

    dbms_lob.fileclose (l_bfile);

    commit;

    l_bfile := bfilename ('MY_FILES','example.doc');

    insert into demo (iid, theblob)

    values (9, empty_blob())

    returning theblob

    into l_blob;

    dbms_lob.fileopen (l_bfile);

    dbms_lob.loadfromfile

        (l_blob,

         l_bfile,

         dbms_lob.getlength (l_bfile));

    dbms_lob.fileclose (l_bfile);

    commit;

  end;

运行成功。

三、利用WebUtil上传大对象文件

declare

       dirnamevarchar2(50);

       filenamevarchar2(50);

       filternamevarchar2(50);

       titlenamevarchar2(50);

       retstrvarchar2(100);

       tablenamevarchar2(10);

       columnnamevarchar2(10);

       whereclausevarchar2(50);

       progresstitlevarchar2(50);

       progressubstitlevarchar2(50);

       asynboolean;

       calltrigvarchar2(50);

       bsuccessboolean;

       nknumber;

       nk1number;

       begin

dirname:='c:\windows\web';

filename:='abc';

filtername:='|jpg file|*.jpg|docfile|*.doc|';

titlename:='打开文件';

retstr:=webutil_file.File_Selection_Dialog(dirname,filename,filtername,titlename);

nk1:=:demo.IID;

tablename:='demo';

columnname:='theblob';

whereclause:='iid='||:demo.IID;

progresstitle:='导入文件进度条';

progressubstitle:='导入文件子进度条';

asyn:=FALSE;

calltrig:=NULL;

bsuccess:=webutil_file_transfer.Client_To_DB(retstr,tablename,columnname,whereclause,asyn,calltrig);

if bsuccess then

retstr:='成功';

:UDLOB_BY_WEBUTIL.TEXT_ITEM65:=retstr;

else

       retstr:='失败';

:UDLOB_BY_WEBUTIL.TEXT_ITEM65:=retstr;

end if;

end;

运行成功,但是文件没有传输到blob中,主要是因为输入IID时,锁定了这个记录。因此这条途径不是很理想。

四、通过服务器端内建程序下载大对象文件

DOWNLOADLOBTOFILE

declare

l_lob blob;

l_amt number;

l_off number;

l_raw raw(1024);

l_varchar varchar2(1024);

kk number;

ii number;

nn number;

fileid UTL_FILE.file_type;

begin

  fileid := UTL_FILE.FOPEN ('MY_FILES', '12345.txt', 'W');

  select theblob into l_lob from demo where iid='24';

  kk:=dbms_lob.getlength(l_lob);

  DBMS_OUTPUT.PUT_LINE ('kk'||to_char(kk));

  ii:=0;

  l_amt:=1024;

  l_off:=1;

   ifkk<=ii then

     dbms_lob.read( l_lob, kk, l_off, l_raw );

       l_varchar:=utl_raw.cast_to_varchar2(l_raw);

       utl_file.put(fileid,l_varchar);

       utl_file.fflush(fileid);

      else

          loop

     if nn<=1024 then

     dbms_lob.read( l_lob, nn, l_off, l_raw );

       l_varchar:=utl_raw.cast_to_varchar2(l_raw);

       utl_file.put(fileid,l_varchar);

       utl_file.fflush(fileid);

           exit;

     else

      dbms_lob.read( l_lob,l_amt, l_off, l_raw );

       l_varchar:=utl_raw.cast_to_varchar2(l_raw);

       utl_file.put(fileid,l_varchar);

       utl_file.fflush(fileid);

         end if;

     ii:=1024+ii;

     DBMS_OUTPUT.PUT_LINE ('ii'||to_char(ii));

     l_off:=ii+1;

     DBMS_OUTPUT.PUT_LINE ('l_off'||to_char(l_off));

     nn:=kk-ii;

     DBMS_OUTPUT.PUT_LINE ('nn'||to_char(nn));

    end loop;

    end if;

 UTL_FILE.fclose (fileid);

end;

这个过程能够下载文件,但是文件不完整,笔者认为是内建函数有bug,所以这个途径不成功!

五、通过WebUtil下载文件大对象文件

declare

       dirnamevarchar2(50);

       filenamevarchar2(50);

       filternamevarchar2(50);

       titlenamevarchar2(50);

       retstrvarchar2(100);

       tablenamevarchar2(10);

       columnnamevarchar2(10);

       whereclausevarchar2(50);

       progresstitlevarchar2(50);

       progressubstitlevarchar2(50);

       asynboolean;

       calltrigvarchar2(50);

       bsuccessboolean;

       nknumber;

       nk1number;

       begin

dirname:='c:\temp';

filename:='abc';

filtername:='|jpg file|*.jpg|docfile|*.doc|';

titlename:='打开文件';

retstr:=webutil_file.File_SAVE_Dialog(dirname,filename,filtername,titlename);

:UDLOB_BY_WEBUTIL.TEXT_ITEM67:=retstr;

nk1:=:demo.IID;

tablename:='DEMO';

columnname:='THEBLOB';

whereclause:='IID='||:demo.IID;

progresstitle:='导入文件进度条';

progressubstitle:='导入文件子进度条';

asyn:=FALSE;

calltrig:='';

bsuccess:=webutil_file_transfer.DB_To_Client(retstr,tablename,columnname,whereclause);

if bsuccess then

retstr:='成功';

:UDLOB_BY_WEBUTIL.TEXT_ITEM67:=retstr;

else

       retstr:='失败';

:UDLOB_BY_WEBUTIL.TEXT_ITEM67:=retstr;

end if;

end;

运行成功!

六、总结和注意

综上所示,笔者认为通过服务器端内建程序实现大对象的上传和通过WebUtil实现大对象的下载是实现大对象上传和下载的可靠途径。

服务器端的程序可以通过sqlplus进行调试,调试时需要屏幕输出,只需每次启动sqlplus都输入以下命令即可。

SET SERVEROUTPUT ON SIZE UNLIMITED(用一个过程,不能超过2000btyes)

SET SERVEROUTPUT ON FOR WRA

 

原创粉丝点击