[原]使用Oracle BFILE 导入文件到数据库一例
最近发现新接手的网站群系统有个非主流的设计——竟然是将文章的正文内容保存在文件中!这导致数据同步和迁移带来了很大的困难,如何将文件的内容重新放进数据库成为了摆在面前的一个问题。
经过搜索,发现Oracle有一种数据类型成为BFILE,可以访问外部的文件,并提供了一系列的过程,例如:dbms_lob.LoadFromFile , dbms_lob.LoadClobFromFile 还有 dbms_lob.LoadBlobFromFile , 大概看名字的就能猜到是做什么的了吧。
使用BFILE访问文件需要首先在数据库中建立 directory ,限定访问路径,当然相应的权限也得跟上:
1 2 | sys$logdw@logserver SQL> create directory cms_data as '/tmp/webapps/cms/cms-data/' ; sys$logdw@logserver SQL> grant read on cms_data to cms ; |
我们再看看表结构:
SQL> desc p_lob_text; Name Null? Type ---------------------- -------- ------------- LOB_ID NOT NULL VARCHAR2(32) KEY_INFO VARCHAR2(100) LOB_CONTENT CLOB LOB_SIZE VARCHAR2(100) LINK_TABLE VARCHAR2(100) LINK_INFO VARCHAR2(50) LINK_CATEGORY VARCHAR2(50) CREATION_TIME VARCHAR2(30) LAST_EDIT_TIME VARCHAR2(30) VERSION NUMBER(38) REMARK VARCHAR2(500) STATIC_FLAG VARCHAR2(3) DELETE_FLAG VARCHAR2(3)
逻辑是这样的,通过lob_id经过变换后可知道文件的位置,然后将该文件导入到对应的clob中。
我写了个过程使用过程、游标进行此操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | declare l_bfile bfile; l_clob clob; l_lob_id varchar (100); l_path varchar (200); -- V_SOURCE NUMBER := 1; V_DEST NUMBER := 1; V_LANG NUMBER := 0; V_WARN NUMBER; -- CURSOR cur is select __id__ from __tablle_name__ where ; begin open cur; loop fetch cur into l_lob_id; EXIT when cur%NOTFOUND; -- 构建文件路径 l_path := '__tablle_name__.' ||l_lob_id|| '.bin' ; -- 有些CLOB是NULL,首先得让它变成 empty clob update __tablle_name__ set __lob_content_field__=empty_clob where id=l_lob_id return __lob_content_field__ INTO l_clob; -- 创建一个bfile对象 l_bfile := bfilename( 'IMPDP_DIR' ,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 ); end if; -- 打开文件后一定要记得关闭哦 dbms_lob.fileclose(l_bfile); end if; commit ; end loop; end ; / |
对于blob要稍微改一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | declare l_directory varchar (200) := '__dir__' ; l_bfile bfile; l_blob blob; l_lob_id varchar (100); l_path varchar (200); V_SOURCE NUMBER := 1; V_DEST NUMBER := 1; V_LANG NUMBER := 0; V_WARN NUMBER; CURSOR cur is select __id__ from __table_name__; begin open cur; loop fetch cur into l_lob_id; EXIT when cur%NOTFOUND; -- setting the path of file l_path := 'blob/adapter_blob.' ||to_char(l_lob_id)|| '.bin' ; update __table_name__ set __blob_field__=empty_blob() where __id__=l_lob_id return content INTO l_blob; l_bfile := bfilename( l_directory,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 dbms_lob.getlength(l_bfile) >0 ) then dbms_lob.loadblobfromfile ( l_blob, l_bfile, DBMS_LOB.LOBMAXSIZE , V_DEST, V_SOURCE ); end if; dbms_lob.fileclose(l_bfile); end if; commit ; end loop; end ; / |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
2009-04-01 [原]Console小技巧——Console版贪食蛇