Oracle blob字段赋值问题

有的时候给Oracle的blob赋值会出现乱码,通常是程序编码的方式和数据用得编码方式不一样。像我之前就是程序用得是UTF-8,而Oracle数据库则是GBK。

总的来所分俩种情况:

  1. 程序和数据编码一致:
    -- 注意rawtohex()函数是用数据库字符编码格式来生成十六进制字符串的
    update act_hi_comment t set t.full_msg_ = rawtohex('哈哈哈哈哈')  where t.id_ = '1234';

  2. 程序和数据编码不一致
    -- 先用程序用自己的编码方式将字符串转换成十六进制字符串
    update act_hi_comment t set t.full_msg_ = '这里是十六进制字符串' where id_ = '111';

create table ACT_HI_COMMENT
(
  id_           NVARCHAR2(64) not null,
  type_         NVARCHAR2(255),
  time_         TIMESTAMP(6) not null,
  user_id_      NVARCHAR2(255),
  task_id_      NVARCHAR2(64),
  proc_inst_id_ NVARCHAR2(64),
  action_       NVARCHAR2(255),
  message_      NVARCHAR2(2000),
  full_msg_     BLOB
);

Oracle 给blob字段设置值的时候,它是可以接收十六进制的值,所以我们可以这样操作:

-- update act_hi_comment t set t.full_msg_ = '这里可以是十六进制字符串';
-- 或者下面这种形式
-- 注意rawtohex()函数是用数据库字符编码格式来生成十六进制字符串的
update act_hi_comment t set t.full_msg_ = rawtohex('哈哈哈哈哈')  where t.id_ = '1234';

如果你的程序显示不是乱码了,那么就看到这里吧。


如果还是乱码,或者想了解更详细就继续往下

首先连接Oracle分thinoci方式:(如:jdbc:oracle:thin:@10.1.1.2:1521:shdb     jdbc:oracle:oci:@shdb   JDBC驱动oci和thin区别

  1. 走jdbc方式连接数据库,则客户端发送数据的编码都是UTF-8;

  2. 走oci方式连接数据库,则根据数据库的编码方式决定客户端的编码方式:

(A)数据库采样UTF-8的时候,客户端发送的编码也是UTF-8;

(B)数据库采用GBK的时候,则客户端发送的编码是GBK。

-- 查看oracle服务端编码:
select * from sys.nls_database_parameters where parameter = 'NLS_CHARACTERSET';
-- ZHS16GBK

-- 查看client编码:
select * from sys.nls_instance_parameters where parameter = 'NLS_LANGUAGE';
-- SIMPLIFIED CHINESE

由上面原因可知,java程序连oracle走JDBC,传的都是UTF-8编码格式的内容;而PLSQL和oralce是走oci去连接的,用的编码是GBK。

这也就是PLSQL里面进行的update,java读取出来后交页面显示是乱码的原因了(PLSQL用GBK编码存进数据库,java用UTF-8解码读出来,编码和解码不一致)。

所以只要保证存进去的时候用UTF-8编码即可。于是我就用java程序把字符按照UTF-8编码成二进制,然后再二进制转十六进制,最后把得到的十六进制的字符串update进去

public class Test {

    public static void main(String[] args) {
        String name = "我是一段字符串";

        System.out.println(bytesToHexString(name.getBytes(StandardCharsets.UTF_8)));
        // E68891E698AFE4B880E6AEB5E5AD97E7ACA6E4B8B2

        // System.out.println(bytesToHexString(name.getBytes(Charset.forName("GBK"))));
        // CED2CAC7D2BBB6CED7D6B7FBB4AE
    }

    public static String bytesToHexString(byte[] bArr) {
        StringBuilder sb = new StringBuilder(bArr.length);
        String sTmp;

        for (byte b : bArr) {
            sTmp = Integer.toHexString(0xFF & b);
            if (sTmp.length() < 2) {
                sb.append(0);
            }
            sb.append(sTmp.toUpperCase());
        }

        return sb.toString();
    }
}
update act_hi_comment t set t.full_msg_ = 'E68891E698AFE4B880E6AEB5E5AD97E7ACA6E4B8B2'  where t.id_ = '1234';

这样就可以搞定了。

(题外话:当中文字符以thin方式存储到数据库时,数据库还是会对照的转换成oracle服务端编码(在这里是GBK);查数据时还好再转回UTF-8。这也就是明明数据库是GBK编码,而Java程序中用UTF-8,却不会乱码的原因)

补充1种Oracle方式:

select convert(UTL_RAW.CAST_TO_VARCHAR2(t.full_msg_), 'zhs16gbk', 'AL32UTF8'), t.* 
from wf.act_hi_comment t  where t.proc_inst_id_ ='415696';

select UTL_RAW.CAST_TO_VARCHAR2(UTL_RAW.CONVERT(t.full_msg_, 'AMERICAN_AMERICA.zhs16gbk', 'AMERICAN_AMERICA.AL32UTF8')) 
from wf.act_hi_comment t  where t.proc_inst_id_ ='415696';

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要更新 Oracle 数据库BLOB 字段,你可以使用以下步骤: 1. 首先,创建一个包含 BLOB 字段的数据表或在已有的表添加 BLOB 字段。 ```sql CREATE TABLE my_table ( id NUMBER, blob_column BLOB ); ``` 2. 使用 UPDATE 语句更新 BLOB 字段的值。你可以使用 PL/SQL 块或 SQL 语句执行此操作。 使用 PL/SQL 块的示例: ```sql DECLARE l_blob BLOB; BEGIN -- 从文件读取新的 BLOB 数据 SELECT empty_blob() INTO l_blob FROM dual; INSERT INTO my_table (id, blob_column) VALUES (1, l_blob); -- 打开 BLOB 对象以进行写入操作 DBMS_LOB.OPEN(l_blob, DBMS_LOB.LOB_READWRITE); -- 写入新的 BLOB 数据 DBMS_LOB.WRITE(l_blob, LENGTHB('New BLOB data'), 1, 'New BLOB data'); -- 关闭 BLOB 对象 DBMS_LOB.CLOSE(l_blob); -- 更新表的记录 UPDATE my_table SET blob_column = l_blob WHERE id = 1; COMMIT; END; / ``` 使用 SQL 语句的示例: ```sql UPDATE my_table SET blob_column = ( SELECT empty_blob() FROM dual ) WHERE id = 1; DECLARE l_blob BLOB; BEGIN SELECT blob_column INTO l_blob FROM my_table WHERE id = 1 FOR UPDATE; -- 打开 BLOB 对象以进行写入操作 DBMS_LOB.OPEN(l_blob, DBMS_LOB.LOB_READWRITE); -- 写入新的 BLOB 数据 DBMS_LOB.WRITE(l_blob, LENGTHB('New BLOB data'), 1, 'New BLOB data'); -- 关闭 BLOB 对象 DBMS_LOB.CLOSE(l_blob); COMMIT; END; / ``` 请注意,这只是一个简单的示例,实际情况可能更复杂。你可能需要根据你的具体需求进行相应的调整。同时,确保在操作 BLOB 字段时进行适当的事务管理和异常处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值