2009-02-24 105 views
1

我想使用raise_application_error-过程来停止登录过程。 我写了一个触发器,它检查TERMINAL字符串,如果它是正确的(我知道这不是真的安全,但起初,它已足够) 因此,触发器工作正常,做我想做的事情,但raise_application_error原因回滚并且不发送我想要的异常。当我用我的应用程序登录数据库时,raise_application_error不会停止应用程序。 第一个问题:这是否是正确的方法,停止使用错误的应用程序登录数据库?第二个问题:如果是,有什么不对?Oracle触发器:raise_application_error

create or replace 
TRIGGER after_logon_on_database 
AFTER LOGON ON DATABASE 
BEGIN 
IF sys_context('USERENV', 'TERMINAL')='IAS' THEN 
    INSERT INTO event_log 
    (event_date, event_time, username, event_case, event_comment) 
    VALUES 
    (SYSDATE, to_char(sysdate, 'hh24:mi:ss'), USER, 'LOGON-SUCCESS', sys_context('USERENV', 'TERMINAL')); 
ELSE 
    INSERT INTO event_log 
    (event_date, event_time, username, event_case, event_comment) 
    VALUES 
    (SYSDATE, to_char(sysdate, 'hh24:mi:ss'), USER, 'LOGON-FAILURE', sys_context('USERENV', 'TERMINAL')); 
    RAISE_APPLICATION_ERROR(-20001, 'Access denied!'); 
END IF; 
END after_logon_on_database; 

回答

0

在IF/ELSE的第二部分添加一个提交; Insert和Raise之间的声明。这将确保登录失败消息正确插入到数据库中。

您知道如果用户是DBA(具有DAB角色),登录触发器不会阻止用户登录。这是一项功能,可确保某人始终可以访问数据库来修复损坏的登录触发器。

你也是正确的,因为触发器不会引发(如Oracle返回的第一条错误消息)错误-20001。它将返回一个-604(ORA-00604:在递归SQL级别1发生的错误)。您不是在登录时直接执行触发器,而是在删除的几个步骤中执行它。你会希望你的应用程序正确处理这个错误。