记一次ORACLE中BLOB文件直接导出的方法测试

2023年 10月 15日 67.1k 0

1、准备下环境

下面简单记录一下实现过程。

首先这个是有个前提条件,包含blob的表里得有1个列是写的真实文件名带扩展后缀,要不然导出的文件没法知道是什么类型的文件。比如说你这个列里即有pdf也有word还有jpg或者压缩包啥的有。

实验基础环境准备如下:

1、准备sqldeveloper软件,下最新版本就行,别搞低版本过来。

2、解锁scott用户,创建一张数据表table_log_test(别问我为啥叫这不搭边的名,测试时随便写的),这张表的数据结构如下表所示:

ID

VARCHAR2(20 BYTE)

CONTENT

BLOB

FILE_NAME

VARCHAR2(200 BYTE)

创建完之后,往里面创建两条数据,扔2个Excel文件

3、数据创建成功后,对数据表进行导出,可以选左侧树中找到数据表,右键--导出(根据实际情况,这里你也可以写sql筛选一下,在结果哪里也可以右键导出。)

参照下图配置:

取消“导出DDL”

勾选“导出数据”

格式修改为“loader"

另存为修改为”单独目录“

文件修改为”你要导出存储BLOB的目录“,这里我选择D:lob。

然后点击下一步

继续下一步

点完成导出文件到本地

导出后显示如下目录内容如下

其中”表名xxxx-xxx-xxx.ldr“命名的就是blob文件

其中”表名.ldr"命名的文件就是记录数据表列内容的文件,

其中”表名.ctl"命名的文件就是控制文件,总的来就是sqlloader那一套东西给图形化了,省了不少事。

至此,基本测试环境准备完毕。下面要说的就是两种把blob导出的原始文件变成真实可用的文件。

2、方法1

--方法1,官方文档的方法

说白了就是使用python脚本进行对原始文件重命名,哈哈哈。

唯一坑的地方就是官方文档里贴出来的python脚本没有格式化,完全没法用,我擦。我和大佬研究了半天才用上。

而且官方文档还给了这么一句,大致就是python脚本只用来Demo的。不是产品,不受支持

还给了你另一个选择,就是一会要说的方法2要说到的用SQLCL+JS脚本来执行。

话接回方法1,虽说是Demo,好歹给格式化一下文件啊,给的脚本长这样。。。。。。。,没有缩进空格的脚本粘贴出来根本无法执行啊。

后来大佬给重新加工了一下脚本,改完之后长这样(使用这个得严格按照说明的3列来进行导出,调换顺序名就串了。。。。):

#该脚本是针对3列,序号|原始文件名|真实文件名,顺序不能错import os
zip_location = input("输入目录:")hdr_file_name = input("输入文件名: ")
f = open(zip_location+"\"+hdr_file_name, "r")command_string = str(f.readline()).split("{EOL}")#cleaning the command listdef command_clean(command_string): for i in command_string: if (i == "" ): command_string.remove(i)
#cleaning up file namedef clean_file_name(name): name = name.replace('"', "") return name
#creating a copy of the specified file and renaming itdef copy_rename(file_name, file_to_name): file_path = zip_location + "\" #file location where it will be renamed and stored. os.rename(file_path + file_to_name,file_path + file_name)
#extracting and separating the file name and file to be renamed (delimiter is the | symbol)def command_extract(command_string): for s in command_string: sep = s.split("|") cmd1 = sep[2].split("\")[-1] cmd2 = sep[1].strip('"') file_name = clean_file_name(cmd1) copy_rename(file_name,cmd2) command_clean(command_string)command_extract(command_string)print('不报错就成功了')

把脚本拷贝到D:lobDATA_TABLE目录下,取名export_data_3column.py

在cmd中登录到该目录下

执行脚本

文件太少了,一闪而过。再检查目录,blob文件己经变成实际的文件名,并可以正常打开查看了。

3、方法2

--方法2,官方文档上说的另1个SQLCL+JS脚本

SQLcl可以认为是SQLPlus的新版本,基于Oracle SQL Developer中的脚本引擎,并附加到一个基于java的命令行界面。除了在命令行上提供更现代的工作方式之外,SQLcl还引入了SQLPlus本身所缺少的新命令和特性。

如何获取SQLcl?

JS脚本一定要在sqlcl下执行!!!

在https://www.oracle.com/database/technologies/appdev/sqlcl.html进行下载,下载后,解压到D盘目录下d:sqlcl

说明一下,运行sqlcl要用JAVA支持,不要下最新版本的JAVA,我试了就出乱码。要用这个版本没毛病,对应的安装包名

jdk-11.0.19_windows-x64_bin.exe

安装JAVA后,配置下JAVA_HOME、配置下系统PATH变量,顺便把sqlcl的bin目录也添加进去,我就不赘述了相信大家都会

配置成功之后,把js脚本放到D:lobDATA_TABLE目录下。

脚本内容如下:

script// issue the SQL var binds = {}var ret = util.executeReturnList('select id,file_name,content from table_log_test',binds); // loop the resultsfor (i = 0; i < ret.length; i++) { // debug IS nice ctx.write( ret[i].ID + "t" + ret[i].FILE_NAME+ "n"); // GET the BLOB stream var blobStream = ret[i].CONTENT.getBinaryStream(1); // GET the path/file handle TO WRITE TO var path = java.nio.file.FileSystems.getDefault().getPath(ret[i].FILE_NAME); // dump the file stream TO the file java.nio.file.Files.copy(blobStream,path); }/!dir

如果你的环境不同看一下说明,注意修改他里的的列名对应你的名称

The file name the blob column names can be changed in the query, but then you’ll ALSO need to change the CONTENT and FILE_NAME attributes for the ret[i] array mentioned on lines 10, 13, & 16.

同样cmd切换到D:lobDATA_TABLE目录下,先执行

sql scott/tigger@192.168.100.20:1521/orcl

登录到数据库

@js_blob.sql执行脚本

执行成功后,显示如下, 文件可以正常查看,问题是文件数量翻倍了。。。。

至此演示结束

4、测试中遇到的坑

坑的地方有2个

第1个是python脚本要严格按照顺序执行,如果你的数据表不是按这个顺序,你可select 调整一下顺序再导出来(这里也可以跟据查询结果筛选文件),然后再按脚本执行,否则你就要修改脚本里的改名规则。

第2个就是写JS的大佬文档里原文FOR用的大写,我研究了好几个小时,一直报i=0;错误,

我后来 才发现下面评论区有人指出错误。。。。。早知先看评论了。哎

文档参考

如何使用sqldeveloper导出blob

https://www.thatjeffsmith.com/archive/2014/05/exporting-multiple-blobs-with-oracle-sql-developer/#:~:text=Open%20the%20Cart%20This%20is%20easy%2C%20just%20access,don%E2%80%99t%20want%20included.%20Click%20the%20%E2%80%98Export%20Cart%E2%80%99%20button

使用sqlcl+js脚本还原真实文件名

https://www.thatjeffsmith.com/archive/2020/07/using-sqlcl-to-write-out-blobs-to-files-in-20-lines-of-js/

官方文档How to Export Multiple BLOB Data, Each To Their Respective Filename (Doc ID 2753958.1)

https://support.oracle.com/knowledge/Middleware/2753958_1.html

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论