5月
15
背景
客户生产系统有张表存储流程bpmn文件,由于某些原因,更新程序找不到,因此只能连接数据库直接更新字段,数据库是oracle数据库,字段类型是blob。
PL/SQL Developer
一开始通过PL/SQL Developer
工具进行编辑,bpmn文件使用UTF-8编码,但是在工具中查看是乱码,因此不能直接编辑

可以点工具上面保存按钮将数据导出到本地文件,导出后打开是正常的,于是本地修改后通过PL/SQL Developer重新导入,但在程序里面读取中文却是乱码的(程序使用java编写),不同工具间转换,编码乱掉也见怪不怪,也不想去折腾工具,想着这种工具问题折腾了也没什么结果。
base64
最万无一失的办法就是导出原始文件,在本地编辑后也导入原始文件,于是想到通过base64作为中间编码进行转换,具体过程为
blob->base64编码->base64解码->获得原始文件->修改文件->base64编码->数据库base64解码->blob
从google上找到Tim Hall大神写的blob和base64的转换程序
base64encode.sqlCREATE OR REPLACE FUNCTION base64encode(p_blob IN BLOB) RETURN CLOB -- ----------------------------------------------------------------------------------- -- File Name : https://oracle-base.com/dba/miscellaneous/base64encode.sql -- Author : Tim Hall -- Description : Encodes a BLOB into a Base64 CLOB. -- Last Modified: 09/11/2011 -- ----------------------------------------------------------------------------------- IS l_clob CLOB; l_step PLS_INTEGER := 12000; -- make sure you set a multiple of 3 not higher than 24573 BEGIN FOR i IN 0 .. TRUNC((DBMS_LOB.getlength(p_blob) - 1 )/l_step) LOOP l_clob := l_clob || UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(DBMS_LOB.substr(p_blob, l_step, i * l_step + 1))); END LOOP; RETURN l_clob; END; /base64decode.sql
CREATE OR REPLACE FUNCTION base64decode(p_clob CLOB) RETURN BLOB -- ----------------------------------------------------------------------------------- -- File Name : https://oracle-base.com/dba/miscellaneous/base64decode.sql -- Author : Tim Hall -- Description : Decodes a Base64 CLOB into a BLOB -- Last Modified: 09/11/2011 -- ----------------------------------------------------------------------------------- IS l_blob BLOB; l_raw RAW(32767); l_amt NUMBER := 7700; l_offset NUMBER := 1; l_temp VARCHAR2(32767); BEGIN BEGIN DBMS_LOB.createtemporary (l_blob, FALSE, DBMS_LOB.CALL); LOOP DBMS_LOB.read(p_clob, l_amt, l_offset, l_temp); l_offset := l_offset + l_amt; l_raw := UTL_ENCODE.base64_decode(UTL_RAW.cast_to_raw(l_temp)); DBMS_LOB.append (l_blob, TO_BLOB(l_raw)); END LOOP; EXCEPTION WHEN NO_DATA_FOUND THEN NULL; END; RETURN l_blob; END; /
着两个funtion可以实现base64和blob之间的转换,base64文本是通过clob字段进行存储。将以上两个sql在oracle中执行即可。
具体步骤如下
- 获得blob的base64文本
select base64encode(t.bytes_) from act_ge_bytearray t where t.id_=6386864;
- 拷贝到本地文本文件中,然后通过base64工具进行还原,如果是mac,可以直接通过base64命令进行解码
base64 -Di base64.txt >process.xml
如果没有工具,可以通过在线工具进行解码,比如这个
- 本地通过文本编辑工具进行编辑,编辑后重新进行编码
base64 process.xml >base64.txt
- 数据库中创建临时表用来存储base64
create table base64_tmp( base64_text clob; )
- 通过工具
PL/SQL Developer
在临时表上新增一条数据,并且拷贝本地的base64保存进去 - 通过update语句进行更新
update act_ge_bytearray t set t.bytes_=(select base64decode(tt.base64_text) from base64_tmp tt) where t.id_=6386864
总结
方法可能有点麻烦,但这是可以想到不通过代码最稳妥的方法,如果你有更好的方法(写代码不算),欢迎评论区留言。
Address: https://zhengjianfeng.cn/?p=642
no comment untill now