проблемы с синтаксисом пакета - PullRequest
0 голосов
/ 22 сентября 2019

Я пытаюсь создать пакет MSGG_SESSION с процедурой аутентификации, которая принимает два параметра VARCHAR2 для имени пользователя и пароля.я полагаю, что нужно поместить закрытую для пакета переменную NUMBER для текущего идентификатора человека. Если «authenticate» совпадает с именем пользователя и паролем в MSGG_USER, поместите соответствующий PERSON_ID в новую переменную.Добавьте функцию get_user_id в пакет, который возвращает значение переменной, содержащей идентификатор человека.

, но я получаю два сообщения об ошибке, говоря, что таблица или представление не завершаются, начиная со второго, до 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;

  /

1 Ответ

1 голос
/ 22 сентября 2019

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