2017-02-28 173 views
0

我正在用這個alter語句測試下面列出的名爲「tulockout」的觸發器......「alter user testuser account lock;」查看觸發器是否記錄表中發生的事件「log_table_changes」。 但是,某些值不準確地登錄到表「log_table_changes」中。具體來說,v_dusr.start_dt在執行「alter user testuser account lock;」後觸發器「tulockout」被觸發時返回NULL。聲明。ORACLE 11g觸發器

我不確定爲什麼。你能協助嗎? 我該如何解決這個問題?謝謝。

create or replace trigger tulockout 
after alter on schema 

declare 

cursor v_abc is 
    select du.username, max(us.start_dt) 
    from dba_users du, user_session us, users_info ui 
    where ui.db_user_name = du.username 
     and ui.db_user_name = us.user_name 
     and ui.db_user_name = ora_login_user; 

v_dusr v_abc%ROWTYPE; 

begin 

    if(ora_sysevent = 'ALTER' and v_dusr.username = ora_dict_obj_name and 
v_dusr.account_status = 'LOCKED') then 

    insert into log_table_changes(username, 
           lastlogin_date, 
           notes, 
           execute_date, 
           script_name 
           ) 
         values(
           v_dusr.username, 
           v_dusr.start_dt, 
           ora_dict_obj_type||', '|| 
           ora_dict_obj_name||' has been locked out.', 
           sysdate, 
           ora_sysevent 
           ); 
end; 

回答

0

你正在聲明一個遊標和一個基於它的記錄;但你永遠不會執行遊標查詢或填充變量。

您的遊標查詢當前缺少group-by子句,因此會在運行時出現錯誤,這是因爲聚合函數。儘管您並不需要在選擇列表中包含用戶名,但您已經知道該值。不過,您後來提到v_duser.account_status字段,該字段在您的遊標查詢/ rowtype中不存在,因此您需要添加(並按其分組)。

觸發器也需要在數據庫而不是模式級別;並且除非您打算記錄執行alter命令的人員,否則您不需要參考ora_login_user - 看起來用戶的狀態似乎不太有用。

你根本不需要光標;一個select-into會做,就像(假設總會有一行從連接返回到你的user_session和users_info表;這意味着他們將用戶名存儲在與dba_users相同的大小寫中 - 儘管我不確定爲什麼你正在加入到在所有users_info):

create or replace trigger tulockout 
after alter on database 
declare  
    v_start_dt user_session.start_dt%TYPE; 
    v_account_status dba_users.account_status%TYPE; 
begin 
    select du.account_status, max(us.start_dt) 
    into v_account_status, v_start_dt 
    from dba_users du 
    join user_session us on us.db_user_name = du.username 
    -- join not needed? 
    -- join users_info ui on ui.db_user_name = us.user_name 
    where du.username = ora_dict_obj_name 
    group by du.account_status; 

    if(ora_sysevent = 'ALTER' and ora_dict_obj_type = 'USER' 
     and v_account_status = 'LOCKED') then 
    insert ... 

,然後在插入使用這些日期和狀態變量和ora_dict_obj_name(這是改變了用戶)。

我也切換到現代連接語法,並調整了一些條件。

未經測試,但應該給你的想法。

通過對這些表執行單個insert ... select,您可以更容易,無需本地變量。

+0

感謝您的回覆。我測試了你的答案,但沒有添加到「log_table_changes」表中。我有「創建或替換觸發器鬱悶 後架構改變」正確,因爲觸發器應該工作了dba_users表status_Account列從開放改爲鎖定。 – caa35

+0

你的問題意味着觸發器正在工作,雖然插入了一些空值;但再看一遍,我不認爲它可以。我認爲它必須是數據庫觸發器,而不是模式?而且這兩個ora_變量只有在用戶鎖定自己的賬戶時纔會匹配 - 我認爲......目前無法進行測試。 –

+0

@ caa35 - 更新了答案,但仍然是錯誤的。 –