根据定义,过程不返回任何内容。您正在寻找一个function http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions256.htm#SQLRF06181.
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;
我对此有点担心,因为它看起来好像您将密码存储为纯文本。这不是最佳实践。
您应该在用户名旁边存储密码的加盐和胡椒散列,然后对密码应用相同的加盐、胡椒和散列,并选择hash从数据库中。
您可以通过以下两种方式之一执行该函数:
select chklg(:pass) from dual
or
declare
l_pass logn.password%type;
begin
l_pass := chklg(:pass);
end;
/
为了完整起见,弗兰克·施密特提出了一个very评论中的观点有效。除了以非常危险的方式存储密码之外,如果两个用户具有相同的密码会发生什么?
您将在您的SELECT INTO ...
。这意味着返回给变量的行太多。如果您也传递用户名,那就更好了。
这可能会使您的函数如下所示
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;