【问题标题】:Execute a stored procedure in oracle在oracle中执行存储过程
【发布时间】:2012-12-13 13:33:03
【问题描述】:

我需要根据提示传递过来的值来获取uu中的输出

create or replace procedure chklg( uu out logn.username%TYPE
                                 , pass in logn.password%TYPE)
is
begin
select username into uu from logn where password=pass;
end; 

我尝试以这种方式执行上述过程:

begin 

chklg(:pass);

end

【问题讨论】:

  • 这种密码验证方法看起来很奇怪。当两个用户的密码相同时会发生什么?此外,正如 Ben 提到的,以纯文本传输密码是完全不行的。提供用户名和密码哈希作为参数,并检查它们是否与数据库中存储的值匹配。

标签: oracle plsql


【解决方案1】:

根据定义,过程不会返回任何内容。您正在寻找function。

create or replace function chklg ( p_pass in logn.password%TYPE
          ) return varchar2 is -- assuming that logn.username%TYP is a varchar2

   l_uu logn.username%type;

begin
   select username into l_uu from logn where password = p_pass;
   return l_uu;
-- If there-s no username that matches the password return null.
exception when no_data_found then
   return null;
end; 

我对此有点担心,因为您似乎将密码存储为纯文本。这不是最佳做法。

您应该在用户名旁边存储密码的盐渍和胡椒散列,然后对密码应用相同的盐渍、胡椒和散列并从数据库中选择 散列。

您可以通过以下两种方式之一执行该功能:

select chklg(:pass) from dual

或

declare
   l_pass logn.password%type;
begin
   l_pass := chklg(:pass);
end;
/

为了完整起见,Frank Schmitt 在 cmets 中提出了一个非常有效的点。除了您以非常危险的方式存储密码之外,如果两个用户使用相同的密码会发生什么?

您将在SELECT INTO ... 中收到 TOO_MANY_ROWS 异常。这意味着太多的行被返回给变量。如果你也传递用户名会更好。

这会让你的函数看起来像下面这样

create or replace function chklg ( 
         p_password_hash in logn.password%type
       , p_username in logn.username%type
          ) return number

   /* Authenticate a user, return 1/0 depending on whether they have
      entered the correct password.
      */

   l_yes number := 0;

begin

   -- Assumes that username is unique.
   select 1 into l_yes 
     from logn
    where password_hash = p_password_hash
      and username = p_username;

   return l_yes;

-- If there-s no username that matches the password return 0.
exception when no_data_found then
   return 0;
end; 

如果您只想使用一个过程(根本没有真正的理由这样做,因为它不必要地限制了您;您没有执行任何 DML),那么您可以获得输出参数,但您必须给出过程它可以填充的参数。

在你的情况下,它看起来像这样。

declare
   l_uu logn.username%type;
begin 
   chklg(l_uu, :pass);
   dbms_output.put_line(l_uu);
end;

【讨论】:

  • 我不能通过将值传递给过程来获取输出参数“uu”的值....
猜你喜欢
  • 1970-01-01
  • 2011-06-19
  • 2014-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-21
  • 2011-11-07
  • 1970-01-01
相关资源
最近更新 更多