我在创建数据库触发器时遇到问题,以便为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的过程。
答案 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;