Oracle触发器调用ora_sql_txt报ORA-00604错误问题咨询
问题解答
关于PLS_INTEGER参数的说明
不存在可修改的PLS_INTEGER相关配置参数,PLS_INTEGER是PL/SQL内置的原生整数类型,存储长度固定,参数调整无法解决当前报错。
异常触发根因
报错和整数类型无关,核心原因是ora_sql_txt函数的返回值类型限制,结合两套数据库的字符集差异导致:
- 系统内置的
ora_name_list_t类型固定定义为VARRAY(64) OF VARCHAR2(64):数组最多容纳64个元素,单个元素最大存储长度为64字节。ora_sql_txt执行时会把完整DDL语句拆分为多个不超过64字节的片段,按顺序存入该数组后返回元素总数。 - 运行正常的数据库字符集为单字节/双字节字符集(如WE8MSWIN1252、ZHS16GBK),2100字符的CREATE TABLE语句拆分后,每个片段的字节长度都不会超过单元素64字节的上限,总长度也远低于数组总容量,因此可以正常执行。
- 报错的数据库使用AL32UTF8等多字节字符集时,语句中包含的中文、全角符号、特殊Unicode字符每个占用3-4字节,拆分过程中如果出现单片段字节长度超64字节、或者多字节字符被切分到两个数组元素边界的情况,就会直接抛出ORA-06502字符串缓冲区过小的错误。
修复方案
12.2版本原生支持ORA_SQL_TXT_FULL函数,直接返回CLOB格式的完整DDL语句,不存在长度限制和字节拆分问题,替换原有的ora_sql_txt调用即可,最小可运行代码如下:
create or replace TRIGGER SCHEMAUSER.TRIGGERNAME AFTER DDL ON SCHEMA DECLARE full_ddl_sql CLOB; BEGIN IF (ora_sysevent ='CREATE' AND ora_dict_obj_type = 'TABLE') THEN full_ddl_sql := ORA_SQL_TXT_FULL(); -- 后续自定义业务逻辑 END IF; END; /
注意不要尝试修改SYS用户下的内置ora_name_list_t类型定义,该操作会破坏数据库内部事件机制,引发全库级别的异常。
内容的提问来源于stack exchange,提问作者Annabett
相关产品推荐
相关产品推荐

