繁体   English   中英

ORACLE 11g扳机

[英]ORACLE 11g Trigger

我正在使用此alter语句测试下面列出的名为“ tulockout”的触发器...“更改用户testuser帐户锁定”。 查看触发器日志是否记录了表“ log_table_changes”中发生的情况。 但是,某些值不能准确地登录到表“ log_table_changes”中。 具体来说,当触发器执行我的“更改用户testuser帐户锁定”触发器后,“ tulockout”将触发,v_dusr.start_dt返回NULL。 声明。

我不确定为什么。 你能帮忙吗? 如何解决此问题? 谢谢。

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;

您正在声明一个游标,并基于该游标进行记录; 但您永远不会执行游标查询或填充变量。

您的游标查询当前缺少group-by子句,由于聚合功能,运行时将出错。 但是,您实际上并不需要在选择列表中包括用户名,因为您已经知道该值。 但是,您稍后会引用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 ,可以使操作变得更加容易,而无需使用局部变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM