但是我有两个错误,说表或视图从not_authenticated_exception之前的第二个开始不退出
和sql语句从priv_number varchar2(100)开始被忽略。
CREATE OR REPLACE PACKAGE MSGG_SESSION IS
PROCEDURE AUTHENTICATE (USERNAME_to_auth IN VARCHAR2, PASSWORD_to_use IN VARCHAR2);
FUNCTION AUTHENTICATED_USER RETURN VARCHAR2;
END MSGG_SESSION;
/
create or replace package body msgg_session is
priv_number varchar2(100);
procedure authenticate (username_to_auth in varchar2, password_to_use in varchar2)
is
not_authenticated exception;
begin
select username
into priv_number
from user_password
where lower(username) = lower(username_to_auth)
and password = password_to_use;
exception
when no_data_found then
begin
raise not_authenticated;
exception
when not_authenticated then
raise_application_error(-20000, 'Not authenticated');
end;
when others then
raise;
end authenticate;
function authenticated_user
return varchar2
is
begin
return null;
end;
function get_user_id
return varchar2
is
begin
return priv_number;
end get_user_id;
end msgg_session;
/
答案 0 :(得分:1)
您没有提供表DDL或错误消息的行号,因此不清楚为什么会得到ORA-00942: table or view does not exist
。检查表的拼写,确保表和包在同一模式中,并且双引号中未定义任何内容(例如user_password
与"user_password"
不同)。
假设表看起来像这样:
create table user_password
( user_id integer constraint user_password_pk primary key
, username varchar2(30) not null constraint user_password_username_uk unique
, password varchar2(30) not null );
带有示例测试数据:
insert into user_password (user_id, username, password)
values (1, 'ndubizuacn', 'Kittens');
软件包的固定版本如下:
create or replace package msgg_session as
procedure authenticate
( username_to_auth in user_password.username%type
, password_to_use in user_password.password%type );
function get_user_id
return user_password.user_id%type;
end msgg_session;
/
create or replace package body msgg_session as
priv_number user_password.user_id%type;
procedure authenticate
( username_to_auth in user_password.username%type
, password_to_use in user_password.password%type )
is
begin
select user_id into priv_number
from user_password
where lower(username) = lower(username_to_auth)
and password = password_to_use;
exception
when no_data_found then
raise_application_error(-20000, 'Not authenticated');
end authenticate;
function authenticated_user
return varchar2
is
begin
return null;
end authenticated_user;
function get_user_id
return user_password.user_id%type
is
begin
return priv_number;
end get_user_id;
end msgg_session;
/
测试:
begin
msgg_session.authenticate('ndubizuacn', 'Kittens');
dbms_output.put_line(msgg_session.get_user_id);
end;
/
假设启用dbms_output
,这将打印值1
。
使用类似这样的全局变量并不能创建一个很好的界面,但这是分配的要求,所以我想它显示了如何使用它。同样需要拨打两次电话-也许您可以扩展authenticated_user
函数以提供备用接口(传递用户名和密码,一次取回user_id)。
以纯文本格式存储密码存在明显的安全风险,有时会说您永远都不要使用任何可以忘记密码的在线服务(如果您忘记密码,这些天这种情况很少见,但是它曾经很常见)。完全不存储密码而是存储ora_hash(upper(username)||'~'||password))
会更安全,例如,对于用户名ndubizuacn
和密码Kittens
,您将存储2160931220
。然后,您的身份验证功能可能类似于:
function authenticated_user
( username_to_auth in user_password.username%type
, password_to_use in user_password.password%type )
return user_password.user_id%type
is
l_user_id user_password.user_id%type;
begin
select user_id into l_user_id
from user_password
where username = username_to_auth
and password_hash = ora_hash(upper(username_to_auth)||'~'||password_to_use);
return l_user_id;
exception
when no_data_found then
raise_application_error(-20000, 'Not authenticated');
end authenticated_user;