小弟刚接触触发器,练习书上的例子,代码如下:
首先建立一个表,以审计在EMP表上执行UPDATE语句的客户主机名,语句及执行时间。
   CREATE TABLE aud_upd_table(
   host varchar2(30),statement varchar2(100),exectime DATE);
上述语句执行成功。
下面建立触发器的语句:
  create or replace trigger tr_upd_emp
  after update on emp
  declare
   sql_txt ora_name_list_t;
   v_stmt varchar2(100);
   n binary_integer;
  begin
   n:=ora_sql_txt(sql_txt);
   for i in 1..n loop
     v_stmt:=v_stmt||sql_txt(i);
   end loop;
   insert into aud_upd_table values(
     sys_context('userenv','host'),v_stmt,SYSDATE);
  END;
也对了,但用以下语句测试时有问题:
 update emp set sql=2000 where empno=7369;
错误提示:
ORA—06502:PL/SQL:numeric or value error
ORA--06512:at "scott.tr_upd_emp", line 7
ORA--04088:error during execution of trigger 'scott.tr_upd_emp'
请各位朋友帮忙看看是什么问题,在线急等哦,谢谢了。
用scott/tiger登录PL/SQL可以测试,希望那位大哥帮忙调试一下。

解决方案 »

  1.   

    应该是FOR循环里面的N没值造成V_STMT为空。ora_sql_txt(sql_txt)应该是个自定义函数,可以看看这个函数是否返回了正确的N值。
    至于sql_txt ora_name_list_t;应该是可变数组。LZ把值打印出来一步步看值。
      

  2.   

    刚才学习并测试了下,主要是这个函数:n:=ora_sql_txt(sql_txt); ora_sql_txt这个函数调用了 dbms_standard.sql_txt(v_sql_text)。这个函数只能中9i中用,10g以后的版本就不能用了,10g返回null.由于返回了null(我的机器上是这样),因此
    for i in 1..n loop  ---这个会报错
    改成:
    for i in 1..nvl(n, 0) loop --OK了,但是loop里面的代码不会执行
      

  3.   

    先desc emp;可能是你的sql,empno字段类型引用(update emp set sql=2000 where empno=7369)有误,两字段分别依下改一下:200,'7367'   '200','7369'  '2008',7369 
      

  4.   

    逻辑没有错误,错误出在了ORA_SQL_TXT函数的使用上。从9206以后的版本,Oracle不再允许DML触发器中使用这个函数,
    只有在系统事件触发器中才能获取到SQL语句。
    试图在DML触发器中使用ORA_SQL_TXT函数,这个函数返回NULL,而且传入的OUT变量将不会被初始化。
      

  5.   

    那么在10G中有没有相应的替代函数?对于ORA_SQL_TXT函数的替代函数?真服了这写书的作者了,10G的书上竟然会有非10G才能用的函数……