首批通过分布式安全可靠测评,为关键业务系统打造
OceanBase 数据库不支持函数调用 Java 程序创建的解密函数的原因及解决方法
更新时间:2026-05-19 08:21
问题现象
用户的应用程序中通过 PL 调用了 Java 程序。迁移之前是原生的 Oracle 上使用函数调用的 Java 程序,使用 MD5 对表进行加密解密,迁移应用到 OceanBase 发现不支持 PL 调用 Java 的函数,需要看下如何处理或者规避。
不支持 PL 调用 Java 写的加密解密函数。
创建的表中有虚拟列,虚拟列不支持调用 UDF 函数。
CREATE OR REPLACE FUNCTION "GIOI"."DECRYPTSTR" ( "P_SRC" IN VARCHAR2 ) RETURN VARCHAR2 DETERMINISTIC IS RESULT VARCHAR2(4000); BEGIN /************************************************* 信息加密函数 descryptStr 入参: P_SRC 输入明文字符串 返回值: RESULT 返回密文字符串,约定返回为 16 进制密文字符串 异常处理: 此函数不对任何异常做捕捉处理,请相应的程序模块对异常做捕捉处理。 **************************************************/ BEGIN --RESULT := 'ERROR DECRPT INFO'; RESULT := decryptStr_tmp(P_SRC); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('SQLCODE : ' || SQLCODE); --DBMS_OUTPUT.PUT_LINE('SQLERRM : ' || SQLERRM); RETURN(RESULT); END; RETURN(RESULT); END decryptStr CHARACTER_SET_CLIENT: utf8mb4 COLLATION_CONNECTION: utf8mb4_general_ci DATABASE COLLATION: utf8mb4_general_ciJava 中
encrypt()方法用于加密数据,方法定义如下。public static String encrypt(String content) throws Exception { return base64Encode(aesEncryptToBytes(content,key)); }
问题原因
问题一: 应用程序中通过 PL 调用了 Java 程序。主要是 OceanBase 数据库目前不支持在 PL 中调用 Java 程序,目前规避方案是提供 UDF 加密解密函数参考。
CREATE OR REPLACE FUNCTION encrypt_base64(input_string IN VARCHAR2) RETURN VARCHAR2 IS key_string VARCHAR2(16) := 'SGVsbG8gV29ybGQ'; -- 替换成你的固定key BEGIN RETURN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(input_string))); END; CREATE OR REPLACE FUNCTION decrypt_base64(input_string IN VARCHAR2) RETURN VARCHAR2 IS key_string VARCHAR2(16) := 'SGVsbG8gV29ybGQ'; -- 替换成你的固定key BEGIN RETURN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_DECODE(UTL_RAW.CAST_TO_RAW(input_string))); END; -- 参考使用方法 SELECT encrypt_base64('hello') FROM dual; -- 输出 Base64 编码后的字符串 SELECT decrypt_base64('aGVsbG8=') FROM dual; -- 输出 Base64 解码后的字符串key_string是在两个函数中被调用的。在encrypt_base64函数中,key_string用作固定的密钥来对输入字符串进行加密。在decrypt_base64函数中,同样地key_string也用作固定的密钥,这时是用来对输入字符串进行解密。问题二: 创建的表中有虚拟列,虚拟列不支持调用 UDF 函数。

虚拟列不支持调用 UDF 函数也是已知问题,规避方法是字段定义成普通列,写个 update 语句插入进去,调用这个加密解密的 UDF 函数
encrypt_base64/decrypt_base64。
问题的风险及影响
OceanBase 数据库 Oracel 模式不兼容(不支持 PL 调用 Java 写的加密解密函数)。
虚拟列定义不支持调用 UDF 函数。
影响租户
影响 OceanBase 数据库中的 Oracle 租户,对于 SYS 租户和 MySQL 租户无影响。
适用版本
OceanBase 数据库所有版本。
解决方法及规避方式
不支持 PL 调用 Java 写的加密解密函数方案是提供 UDF 加密解密函数参考上文问题原因模块有详细描述。
虚拟列定义不支持调用 UDF 函数, 规避方法是字段定义成普通列,写个 update 语句插入进去,调用这个加密解密的 UDF 函数。