【问题标题】:Function to verify username and password in pl/sql [closed]在pl / sql中验证用户名和密码的功能[关闭]
【发布时间】:2012-02-18 02:21:27
【问题描述】:

我有一个名为 BANKCUSTOMER 的表,其中包含以下列:

 USERNAME                                  NOT NULL VARCHAR2(11)
 FAMILY_NAME                               NOT NULL VARCHAR2(25)
 NAME                                      NOT NULL VARCHAR2(25)
 PASSWD                                    NOT NULL VARCHAR2(6)

如果用户 USERNAME 和 PASSWORD 与数据库中的数据匹配,我想创建一个检查数据库的函数。如果登录成功,那么它应该打印出“登录成功!”否则“用户名或密码错误!”

我访问了一个 pl/sql 教程网站,看到了以下代码,我对其进行了一些修改,以便它可以与我的数据库一起使用,但是有些东西我不明白,这就是 z number 所做的和 @ 987654323@ 可以。有人可以为我解释一下。

create or replace function log_in(x in varchar2, y in varchar2)   
return varchar2  
as  
  z number;  
begin  
  select 1  
    into z   
    from bankcustomer   
    where username=x   
    and passwd=y;  
  dbms_output.put_line('Login successful!');  
exception  
when no_data_found then  
  dbms_output.put_line('Wrong username or password!'); 
end; 

我想通过写SELECT log_in() FROM dual; 来测试这个功能,看看它是否有效。当我写 SELECT log_in() FROM dual; 时,我收到一条错误消息:

从命令的第 1 行开始出错: 从双重选择登录() 命令行错误:1 列:7 错误报告: SQL 错误:ORA-06553:PLS-306:调用“LOG_IN”时参数的数量或类型错误 06553. 00000 - “PLS-%s: %s” *原因:
*行动:

如何解决?

【问题讨论】:

    标签: sql oracle oracle11g ora-06553


    【解决方案1】:

    您已经定义了一个函数,但没有从它返回值。鉴于您“选择”该函数,因此无需使用 dbms_output:

    create or replace function log_in(x in varchar2, y in varchar2)
    return varchar2
    as
      match_count number;
    begin
      select count(*)
        into match_count
        from bankcustomer
        where username=x
        and passwd=y;
      if match_count = 0 then
        return 'Wrong username or password!';
      elsif match_count = 1 then
        return 'Login successful!';
      else
        return 'Too many matches, this should never happen!';
      end if;
    end;
    /
    

    此外,您对该函数的调用未提供用户名和密码参数,这就是您收到错误消息的原因。假设您已将函数更改为实际返回某些内容,则需要使用

    SELECT log_in('username', 'secretpassword') FROM dual;
    

    【讨论】:

    • 非常感谢您的帮助!它真的帮助我理解了整个事情(解释了为什么我不需要使用 dbms_output)。
    【解决方案2】:

    您实际上是否将任何参数传递给log_in 函数? logga_in() 是什么?后者是你的错字吗?

    无论如何,select 1 into z 只会在找不到匹配项的情况下强制异常。仅此而已。

    换句话说,您可以在没有它的情况下编写代码,例如使用select count(*) into authenticated ...,然后您可以检查if authenticated != 0 并执行适当的操作。我没有Oracle实例,所以这段代码是瞎写的,你需要测试一下:

    create or replace function log_in(x in varchar2, y in varchar2)
    return varchar2
    as
      match_count number;
    begin
      select count(*)
        into match_count
        from bankcustomer
        where username=x
        and passwd=y;
      if match_count = 0 then
        dbms_output.put_line('Wrong username or password!');
      elsif match_count = 1 then
        dbms_output.put_line('Login successful!');
      else
        dbms_output.put_line('Too many matches, this should never happen!');
    end;
    

    【讨论】:

    • 您需要将用户名和密码传递给函数。喜欢SELECT log_in('Posidon', 'FooBarPassword') from dual
    • 误删了我的答案。好吧,现在我明白你的意思了。明天我会试一试 :) 如果你能通过select count(*) into authenticated 和检查if authenticated !=0 向我展示解决方案,我将非常感激。我应该用什么来代替as z number 非常感谢您的帮助!
    【解决方案3】:

    只是为了向已经提供的内容添加更多信息,BEGIN 关键字表示执行块的开始;上面是函数头和任何声明语句。

    语句z number;是一个变量声明语句,声明了一个名为z并且数据类型为number的变量。 SELECT 1 INTO z WHERE... 语句正在检查 BANKCUSTOMER 表中的行,其中用户名与第一个参数中传递给函数的内容相匹配,密码与第二个参数中传递给函数的内容相匹配。

    如果有一行用户名和密码与传递给函数的内容匹配,则变量 z 将包含数字 1。如果不存在,Oracle NO_ROWS_FOUND exception 将被引发,因为 SELECT...INTO 语句必须始终选择只有一行,否则它们会引发异常(NO_ROWS_FOUND exception 表示没有行,TOO_MANY_ROWS exception 表示多行)。

    希望对您有所帮助!如果您还有其他问题,请随时提问。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-21
      • 1970-01-01
      相关资源
      最近更新 更多