2012-10-09 53 views
1

我有一个触发器,它应该测试是否有人在最后5分钟内冲出时间卡。如果他们没有将他们的信息留给表clk_data,否则应该在日志表utl_logbook中创建一条记录,并且应该中止对clk_data的插入。oracle触发日志

当我运行一个良好的拳头插入作品广告。当它是一个糟糕的冲我得到以下错误(5分钟的最后一拳之内):

SQL Error: ORA-20101: Too Soon 
ORA-06512: at "TRUTRACK.INSERT_CLK_DATA", line 14 
ORA-04088: error during execution of trigger 'TRUTRACK.INSERT_CLK_DATA' 

停止交易,但我没有得到任何它记录在utl_logbook。

The trigger code: 
create or replace 
TRIGGER "INSERT_CLK_DATA" 
BEFORE INSERT ON clk_data 
FOR EACH row 

BEGIN 
    DECLARE qty INTEGER := 0; 
    BEGIN 
    SELECT COUNT(*) 
    INTO qty 
    FROM clk_data 
    WHERE clk_time BETWEEN (:new.clk_time - 5/(24*60)) AND (:new.clk_time + 5/(24*60)) 
    AND :new.payroll = clk_data.payroll; 

    IF qty > 0 THEN 

     INSERT INTO utl_logbook (time, source, message) VALUES (sysdate, 'INSERT_CLK_DATA', 'Clock punch within restricted window. Payroll ID:' || :new.payroll || ' Time: ' || :new.clk_time || ' Type: ' || :new.type); 

     RAISE_APPLICATION_ERROR(-20101, 'Too Soon'); 

    END IF; 

    END; 
END; 

回答

2

这可以是您可以使用pragma autonomous_transaction时的罕见情况之一。它将允许您提交而不影响您的主要交易。谨慎使用它。了解更多有关autonomous transactionsautonomous_transaction pragma

下面是一个例子:

-- our error logging table 

    create table tb_log(
     msg varchar2(123) 
    ) 
    /

    -- our working table 
    create table tb_table(
    col11 number 
    ) 
    /

-- procedure that is going to log errors 


[email protected]> create or replace procedure log_error(p_msg in varchar2) 
    2 is 
    3  pragma autonomous_transaction; 
    4 begin 
    5  insert into tb_log(msg) 
    6  values(p_msg); 
    7  commit; 
    8 end; 
[email protected]>/

Procedure created. 

[email protected]> create or replace trigger tr_tb_table 
    2 before insert on tb_table 
    3 for each row 
    4 begin 
    5  if mod(:new.col1, 2) != 0 
    6  then 
    7   log_error('Error!'); 
    8   raise_application_error(-20000, 'Error has ocurred!'); 
    9  end if; 
10 end; 
11/

Trigger created. 

[email protected]> select * from tb_log; 

no rows selected 

[email protected]> select * from tb_table; 

no rows selected 

[email protected]> insert into tb_table(col1) values(1); 

insert into tb_table(col1) values(1) 
      * 
ERROR at line 1: 
ORA-20000: Error has ocurred! 
ORA-06512: at "NK.TR_TB_TABLE", line 5 
ORA-04088: error during execution of trigger 'NK.TR_TB_TABLE' 


[email protected]> select * from tb_log; 

MSG 
-------------------------------------------------------------------------------- 
Error! 
+0

谢谢。这工作很好。 – user1732495

1

@尼古拉斯 - 克拉斯诺夫提供的解决方案,只是阐述了几分道理 - 你在触发器主体抛出一个异常:

RAISE_APPLICATION_ERROR(-20101, 'Too Soon'); 

这会导致事务回滚。这全部细节,可以发现:

http://psoug.org/reference/exception_handling.html

If the statement fails, Oracle rolls back to the savepoint. Normally, just the failed SQL statement is rolled back, not the whole transaction. However, if the statement raises an unhandled exception, the host environment determines what is rolled back.