oracle 从os文件读blob,从表中读blob写到os文件中

来源:互联网 发布:结对编程搞笑图片 编辑:程序博客网 时间:2024/05/18 03:04

oracle 从os文件读blob,从表中读blob写到os文件中。

今天一个朋友问我如何将数据库中blog转存到操作系统上,由于量比较大,有java效率很低,顾决定翻书查资料使用oracle的系统包来完成。主要涉及的表为操作lob的dbms_lob包和操作文件的utl_file包。虽然花费了5,6个小时,但是也学到了不少东西,生命在于折腾吧。
create or replace function readblobbyparh/*    *从给定的directory(路径)和文件名读取图片到blob并返回    *dir oracle directory 对象名    *filename 文件名+.后缀    */(    dir      varchar2,    filename varchar2) return blob is    v_dir    varchar2(30);    temfile  utl_file.file_type;    isexist  boolean;    lens     number;    blocklen number;    temblob  blob;    buffers  raw(2000);begin    v_dir := upper(dir);    --一定要初始化temblob,使用empty_blob()是不行的,真是大坑啊。    dbms_lob.createtemporary(temblob, true);    --获得文件句柄    temfile := utl_file.fopen(location => v_dir, filename => filename, open_mode => 'rb');    --获取文件的属性,这里主要是获取长度    utl_file.fgetattr(location    => v_dir,                      filename    => filename,                      fexists     => isexist,                      file_length => lens,                      block_size  => blocklen);    --循环读取内容到内存中,有长度限制,同时raw的长度/2=字符长度    for i in 1 .. (trunc(lens / 2000) + 1)    loop        --读取        utl_file.get_raw(file => temfile, buffer => buffers, len => 2000);        --追加写        dbms_lob.writeappend(lob_loc => temblob, amount => length(buffers) / 2, buffer => buffers);    end loop;    -- dbms_output.put_line(temblob);    utl_file.fclose(file => temfile);    return temblob;end;create or replace procedure writeblobtofile/*    *将给定的blob输出到给定文件中(directorey+filename)    *fromblob 数据库的blob    *dir oracle directory 对象名    *filename 文件名+.后缀    */(    fromblob blob,    dir      varchar2,    filename varchar2) is    v_dir   varchar2(30);    temfile utl_file.file_type;    lens    number;    buffers raw(2000);    amount  number := 2000;begin    --空的blob,直接返回    if length(fromblob) = 0    then        raise_application_error(-20001, 'blob对象为空!对应的filename=' || filename);    end if;    v_dir   := upper(dir);    temfile := utl_file.fopen(location => v_dir, filename => filename, open_mode => 'wb');    lens    := dbms_lob.getlength(lob_loc => fromblob);    for i in 1 .. (trunc(lens / 2000) + 1)    loop        dbms_lob.read(lob_loc => fromblob,                      amount  => amount,                      offset  => ((i - 1) * 2000 + 1),                      buffer  => buffers);        dbms_output.put_line(amount);        -- dbms_output.put_line(length(buffers) / 2);        utl_file.put_raw(file => temfile, buffer => buffers);    end loop;end;测试--创建directory 对象create or replace directory mydir as '/u01/';--授权,如果directory是scott创建的则无须授权grant read,write on directory mydir to scott;--核实scott对木有有读写权限select * from all_directories;select * from user_tab_privs;drop table t1 purge;create table t1 (name varchar2(200),contexts blob);--将os上的图片写到数据库中的blob中insert into t1 values ( 'name1.jpg',readblobbyparh(dir => 'mydir', filename =>'1.jpg' ));insert into t1 values ( 'name2.jpg',readblobbyparh(dir => 'mydir', filename =>'1.jpg' ));commit;--查看表中有图片了select * from t1;--从表中读blob到os上begin    for i in (select *                from t1 a               where a.contexts is not null)    loop        writeblobtofile(fromblob => i.contexts, dir => 'mydir', filename => i.name);    end loop;end;--查看mydir这个directory对象下有没有相应的文件


0 0
原创粉丝点击