在执行触发器时获取额外消息

时间:2012-01-31 19:03:04

标签: oracle plsql triggers oracle-apps

我在创建数据库触发器时遇到问题,以便为oracle表单引发错误消息。你能帮帮我吗?

我的代码是:

CREATE OR REPLACE TRIGGER unsuccessful_attempts_lock
      BEFORE UPDATE of last_logon_date 
ON temp_user
FOR EACH ROW

DECLARE
CURSOR c_unsuccessful_attempts IS
  SELECT *
  FROM temp_unsuccessful_attempts
  WHERE user_id=:NEW.user_id; 
max_fails EXCEPTION;

BEGIN
   FOR r_unsuccessful_attempts IN c_unsuccessful_attempts
   LOOP
     IF(r_unsuccessful_attempts.locked ='Y') THEN
       RAISE max_fails;
     END IF;
   END LOOP;
EXCEPTION
  WHEN max_fails THEN
  FND_MESSAGE.SET_NAME ('FND', 'FLEX-USER DEFINED ERROR');
  FND_MESSAGE.SET_TOKEN ('MSG', 'You have reached maximum failed logins. 
                This account has been locked temporarily. Please contact 
                your system administrator')
  FND_MESSAGE.RAISE_ERROR;
  WHEN OTHERS THEN
  RAISE_APPLICATION_ERROR(-20400,'An error has occured.Please contact 
                 your system administrator'||SQLCODE||SQLERRM);
END unsuccessful_attempts_lock;

一旦用户的帐户被锁定,temp_unsuccessful_attempts.locked将更新为“Y”,并且他/她应该无法进一步登录。 temp_user是在用户成功登录时更新的表。

因此,一旦用户的帐户被锁定(temp_unsuccessful_attempts.locked='Y'),然后如果他将尝试使用正确的密码登录,则触发器应该触发(在更新temp_user表时)和表单应该给出一个错误,即他的帐户已被锁定,不应该进一步发展。

我收到的消息是:

  

ORACLE错误-20001:ORA-20001:FLEX-USER DEFINED错误:N,MSG,你   已达到最大失败登录次数。请联系您的系统   管理员。

     

ORA-06512:at“APPS.FND_MESSAGE”,第66行

     

ORA-06512:at“APPS.UNSUCCESSFUL_ATTEMPTS_LOCKS”,第38行

     

ORA-04088:执行触发期间出错   已检测到“APPS.UNSUCCESSFUL_ATTEMPTS_LOCKS”   FND_SIGNON.NEW_SESSION。

我的触发器在我的oracle应用程序屏幕上提供了一些额外的消息。我只是想显示

  

您已达到最大失败登录次数。您的帐户已暂时锁定。请与您的服务台联系。

P.S:FND_SIGNON.NEW_SESSION是更新temp_user.last_logon_date的过程。

1 个答案:

答案 0 :(得分:2)

这里我们使用一个得到堆栈第一个错误的函数:

function strip_first_error(pcode in number, pmessage in varchar2) return varchar2 is
    --
    vpos number := instr(pmessage, 'ORA-', 5);
    --
  begin
    if pcode between 20000 and 20999 then
      if vpos != 0 then
        return( substr(substr(pmessage, 1, vpos -2 ),12) );
      else
        return( substr(pmessage,12) );
      end if;
    else
      return pmessage;
    end if;
  end;

用法是:

when others then
    message(strip_first_error(abs(sqlcode), sqlerrm));

修改

P.S。:这是其他人在你update的电话中处理错误的时候。在您的具体示例中应该是:

begin
  update last_logon_date ...
exception
    when others then
      -- in forms you should use message or other function that display the error
      -- in pl/sql you should use dbms_output.put_line, for example.
      dbms_output.put_line( strip_first_error(abs(sqlcode) , sqlerrm) );
end;