2009-02-24 107 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發生的錯誤)。您不是在登錄時直接執行觸發器,而是在刪除的幾個步驟中執行它。你會希望你的應用程序正確處理這個錯誤。