Вы не предоставляете таблицу 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;