问题现象
Oracle 数据库与 OceanBase 数据库的 Oracle 租户执行下述一样的操作,创建测试表。
obclient > create table U_LXL.test_clob(
id number(10),
str_c clob,
primary key (id)
);
obclient > insert into U_LXL.test_clob values(1,to_clob('hello world'));
obclient > insert into U_LXL.test_clob values(2,to_clob('hello world'||utl_raw.cast_to_varchar2('A3B4')));
obclinet> commit;
Oracle 数据库查询 clob 字段对应的哈希值。
SQL> select id,DBMS_CRYPTO.HASH(str_c,3) md_value from U_LXL.test_clob;
ID MD_VALUE
---------- ----------------------------------------
1 2AAE6C35C94FCFB415DBE95F408B9CE91EE846ED
2 372AA8C34C3C0DEF2580FCDD990DE854C8915310
OceanBase 数据库的 Oracle租户查询 clob 字段对应的哈希值。
obclient [SYS]> select id,DBMS_CRYPTO.HASH(str_c,3) md_value from U_LXL.test_clob;
+----+------------------------------------------+
| ID | MD_VALUE |
+----+------------------------------------------+
| 1 | 2AAE6C35C94FCFB415DBE95F408B9CE91EE846ED |
| 2 | 82260BF2D01F0CAC6688183C0EA1F63C72884566 |
+----+------------------------------------------+
从上述例子,可以看到:
ID=1 的记录,Oracle 数据库与 OceanBase 数据库的结果是一致的,根据实测结果,大多数记录也是如此。
ID=2 的记录,Oracle 数据库与 OceanBase 数据库的结果是不一致的,目前仅发现部分字符会触发这种现象。
适用版本
OceanBase 数据库 V2.x、V3.x 版本。
问题原因
OceanBase 数据库的 Oracle 模式下 to_clob 和 to_char 遇到不可识别的字符时,行为与 oracle 不兼容。
解决方法
如果仅仅需要实现对比 Oracle 数据库与 OceanBase 数据库之间的数据一致性的话,我们可以通过 UTL_RAW.CAST_TO_RAW 函数,先转一次 RAW 值,再入 CLOB,以免遇到不可识别的字符。
示例:
obclient [SYS]> select dbms_crypto.hash(utl_raw.cast_to_raw('Hash'||rowid),2) hash_val from U_LXL.test_clob;
输出结果如下:
+----------------------------------+
| HASH_VAL |
+----------------------------------+
| 8052582E47EAA4BD1D83A7DF137253D8 |
| A604D1AFB51A71EE026033FE0AB35920 |
+----------------------------------+
2 rows in set (0.164 sec)