使用Oracle BFILE 导入文件到数据库
如何将文章的正文内容保存在文件中?这导致数据同步和迁移带来了很大的困难,如何将文件的内容重新放进数据库成为了摆在面前的一个问题。经过搜索,发现Oracle有一种数据类型成为BFILE,可以访问外部的文件,并提供了一系列的过程,例如:dbms_lob.LoadFromFile,dbms_lob.LoadClobFromFile还有dbms_lob.LoadBlobFromFile,大概看名字的就能猜到是做什么的了吧。
使用BFILE访问文件需要首先在数据库中建立Directory,限定访问路径,当然相应的权限也得跟上:
sys$logdw@logserverSQL>createdirectorycms_dataas'/tmp/webapps/cms/cms-data/';
sys$logdw@logserverSQL>grantreadoncms_datatocms;
我们再看看表结构:
SQL>descp_lob_text;
NameNull?Type
-------------------------------------------
LOB_IDNOTNULLVARCHAR2(32)
KEY_INFOVARCHAR2(100)
LOB_CONTENTCLOB
LOB_SIZEVARCHAR2(100)
LINK_TABLEVARCHAR2(100)
LINK_INFOVARCHAR2(50)
LINK_CATEGORYVARCHAR2(50)
CREATION_TIMEVARCHAR2(30)
LAST_EDIT_TIMEVARCHAR2(30)
VERSIONNUMBER(38)
REMARKVARCHAR2(500)
STATIC_FLAGVARCHAR2(3)
DELETE_FLAGVARCHAR2(3)
逻辑是这样的,通过lob_id经过变换后可知道文件的位置,然后将该文件导入到对应的clob中。
我写了个过程使用过程、游标进行此操作:
declare
l_bfilebfile;
l_clobclob;
l_lob_idvarchar(100);
l_pathvarchar(200);
--
V_SOURCENUMBER:=1;
V_DESTNUMBER:=1;
V_LANGNUMBER:=0;
V_WARNNUMBER;
--
CURSORcuris
selectLOB_ID
fromp_lob_text;
begin
opencur;
loop
fetchcurintol_lob_id;
EXITwhencur%NOTFOUND;
--构建文件路径
l_path:=substr(l_lob_id,0,4)
||'/'||substr(l_lob_id,5,2)
||'/'||substr(l_lob_id,7,2)
||'/'||l_lob_id;
--有些CLOB是NULL,首先得让它变成emptyclob
updatep_lob_text
setlob_content=empty_clob
whereLOB_ID=l_lob_id
returnlob_contentINTOl_clob;
--创建一个bfile对象
l_bfile:=bfilename('CMS_DATA',l_path);
--判断文件是否存在
if(dbms_lob.fileexists(l_bfile)=1)then
--重设一些参数
V_SOURCE:=1;
V_DEST:=1;
V_LANG:=0;
--打开文件
dbms_lob.fileopen(l_bfile);
if(
--判断文件是否打开
dbms_lob.fileisopen(l_bfile)=1
and
--判断文件的长度是否为了0
dbms_lob.getlength(l_bfile)>0
)then
--将文件Load到clob字段中
dbms_lob.loadclobfromfile
(l_clob,
l_bfile,
DBMS_LOB.LOBMAXSIZE,
V_DEST,
V_SOURCE,
0,V_LANG,V_WARN
);
endif;
--打开文件后一定要记得关闭哦
dbms_lob.fileclose(l_bfile);
endif;
commit;
endloop;
end;
/