2017-02-28 10 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 Trigger

私はその理由について確信していません。助けてもらえますか? この問題を解決するにはどうすればよいですか?ありがとう。

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

カーソルとそれに基づいてレコードを宣言しています。カーソル問合せを実行したり、変数を移入したりすることはありません。

カーソルクエリには現在グループバイ句がありません。したがって、集計関数のため実行時にエラーが発生します。あなたはすでに値を知っているので、あなたは本当に選択リストにユーザー名を含める必要はありません。あなたは、後でv_duser.account_statusフィールドを参照していますが、それはあなたのカーソルクエリ/行タイプには存在しないので、あなたはそれを追加(およびグループ化)する必要があります。

トリガーもスキーマレベルではなく、データベースにある必要があります。あなたが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"テーブルにnothingsが追加されました。トリガがdba_usersテーブルのstatus_AccountカラムをOPENからLOCKEDに変更する必要があるため、「スキーマの変更後にトリガtulockout を作成または置き換えてください。 – caa35

+0

あなたの質問は、いくつかのヌル値を挿入していますが、トリガが機能していたことを示しています。しかし、それをもう一度見て、私はそれができたとは思わない。スキーマではなく、データベースのトリガーでなければならないと思いますか?そして、2つのora_変数は、ユーザーが自分のアカウントをロックしている場合にのみ一致します - 私は...現時点ではテストできないと思います。 –

+0

@ caa35 - 答えを更新しましたが、依然としてテクスチャーはありません。 –