ORA-06502报错:通过ora_sql_txt在DDL审计表存储执行SQL的方法咨询
ORA-06502报错原因分析
- 第一,
ora_sql_txt函数返回的是ORA_NAME_LIST_T类型的字符串集合,不能直接作为字符串插入varchar类型字段,必须先拼接为完整SQL文本再写入。 - 第二,现有表结构中
SQL_TT字段仅定义为varchar(100),绝大多数DDL语句长度都会超过100字节,插入时触发长度溢出错误。
正确实现方案
步骤1:修改表结构,调整SQL_TT字段类型
建议使用CLOB类型存储完整DDL文本,避免超长场景的溢出问题:
ALTER TABLE AAUDIT_DDL MODIFY SQL_TT CLOB; -- 若不需要存储超长DDL,也可至少调整为VARCHAR2(4000)(Oracle默认普通字符串最长长度) -- ALTER TABLE AAUDIT_DDL MODIFY SQL_TT VARCHAR2(4000);
步骤2:修改触发器逻辑,拼接完整SQL后插入
create or replace trigger aaudit_ddl after ddl on DATABASE declare l_sql_pieces ORA_NAME_LIST_T; l_piece_cnt PLS_INTEGER; l_full_sql CLOB; begin if (ora_sysevent='REVOKE') then null; -- 忽略REVOKE操作 else -- 读取ora_sql_txt返回的SQL片段并拼接为完整语句 l_piece_cnt := ora_sql_txt(l_sql_pieces); FOR i IN 1..l_piece_cnt LOOP l_full_sql := l_full_sql || l_sql_pieces(i); END LOOP; insert into aaudit_ddl(d, osuser,current_user,host,ip_address,terminal,owner,OBJECT_TYPE,OBJECT_NAME,DDL_TYPE,SQL_TT) values( sysdate, sys_context('USERENV','OS_USER') , sys_context('USERENV','CURRENT_USER') , sys_context('USERENV','HOST') , SYS_CONTEXT('USERENV','IP_ADDRESS'), sys_context('USERENV','TERMINAL') , ora_dict_obj_owner, ora_dict_obj_type, ora_dict_obj_name, ora_sysevent, l_full_sql ); end if; end; /
注意事项
- 数据库级触发器需要使用SYS用户、或拥有
ADMINISTER DATABASE TRIGGER权限的用户创建,否则会触发权限不足错误。 - 建议定期清理AAUDIT_DDL表的历史数据,避免日志量过大占用存储资源。
内容的提问来源于stack exchange,提问作者Алексей Брик
相关产品推荐
相关产品推荐

