【问题标题】:ORA-06502: PL/SQL: numeric or value error by ora_sql_txtORA-06502: PL/SQL: ora_sql_txt 的数字或值错误
【发布时间】:2021-12-26 11:17:57
【问题描述】:

我有 ddl 日志表。在这张表中,我还想看看哪些代码是完全完成的。如何将其放入 sql_tt 列?你能提示我这个吗?

CREATE TABLE AAUDIT_DDL (
d date,
OSUSER varchar2(255),
CURRENT_USER varchar2(255),
HOST varchar2(255),
IP_ADDRESS   VARCHAR2(100 CHAR),
TERMINAL varchar2(255),
owner varchar2(30),
OBJECT_TYPE varchar2(30),
OBJECT_NAME varchar2(30),
DDL_TYPE varchar2(30),
SQL_TT varchar(100));

并触发

create or replace trigger aaudit_ddl after ddl on DATABASE

begin
if (ora_sysevent='REVOKE')
then
null; -- I do not care about REVOKE
else
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,
  ora_sql_txt
  );
  end if;
  end;
 /

【问题讨论】:

    标签: sql oracle plsql triggers


    【解决方案1】:

    Documentation 建议对ora_sql_txt 使用不同的方法:因为函数需要IN 参数(它是一个整数,表示PL/SQL 表中元素的数量),你应该

    CREATE TABLE event_table (col VARCHAR2(2030));
    
    DECLARE
      sql_text   ora_name_list_t;
      n          PLS_INTEGER;
      v_stmt     VARCHAR2(2000);
    BEGIN
      n := ora_sql_txt(sql_text);
    
      FOR i IN 1..n LOOP
        v_stmt := v_stmt || sql_text(i);
      END LOOP;
    
      INSERT INTO event_table VALUES ('text of triggering statement: ' || v_stmt);
    END;
    

    【讨论】:

      【解决方案2】:

      这就是我的设置,它工作正常。

      
       --Table will be created by sys user with tbs_audit as tablespace as default tablespace for audit table AUDIT_DDL
      
      CREATE TABLE AUDIT_DDL ( 
      DDL_DATE date, 
      OSUSER varchar2(255),
      CURRENT_USER varchar2(255),
      HOST varchar2(255), 
      TERMINAL varchar2(255), 
      IP_ADDRESS VARCHAR2(100), 
      module varchar2(100),
      owner varchar2(30), 
      type varchar2(30), 
      name varchar2(30), 
      sysevent varchar2(30),
      sql_txt varchar2(4000) ) 
      tablespace tbs_audit ;
      
      --- Trigger will be created at sys user, so that all statements will be captured in any schema in the database
      
      create or replace trigger
      sys.audit_ddl_trg after ddl on database
      declare
      sql_text ora_name_list_t;
      stmt VARCHAR2(4000) := '';
      n number;
      begin
      n:=ora_sql_txt(sql_text);
      for i in 1..n
      loop
      stmt:=substr(stmt||sql_text(i),1,4000);
      end loop;
      insert into audit_ddl(
      DDL_DATE,osuser,
      current_user,host,
      terminal,
      ip_address,module,
      owner,
      type,name,sysevent,sql_txt)
      values(
      sysdate,
      sys_context('USERENV','OS_USER') ,
      sys_context('USERENV','CURRENT_USER') ,
      sys_context('USERENV','HOST') ,
      sys_context('USERENV','TERMINAL') ,
      UTL_INADDR.get_host_name('USERENV'),
      sys_context('USERENV','MODULE') ,
      ora_dict_obj_owner,
      ora_dict_obj_type,
      ora_dict_obj_name,
      ora_sysevent,
      stmt
      );
      end;
      /
      
      -- Sql Query can be used to lookup the captured ddl in the audit_ddl table.
      col type format a10
      col name format a10
      col host format a16
      col IP_ADDRESS format a10
      col terminal format a20
      col owner format a15
      col sql_txt format a20
      col SYSEVENT format a10
      col CURRENT_USER format a10
      col osuser format a10
      select * from AUDIT_DDL;
      
      

      【讨论】:

        猜你喜欢
        • 2014-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-18
        • 2014-12-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多