4

我在创建数据库触发器以引发 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”,他/se 将无法进一步登录。并且temp_user是在用户成功登录时更新的表。

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

我收到的消息是:

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

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

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

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

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

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

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

4

1 回答 1

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));

编辑

PS:这是其他人在您的调用中处理错误的时候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;
于 2012-01-31T19:33:35.690 回答