您的位置:首页 > 数据库 > Oracle

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

2016-05-15 00:43 615 查看

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对象下有没有相应的文件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: