1

我对 oracle 包非常陌生,想知道是否有人可以解释为什么这不会编译/执行。

CREATE OR REPLACE PACKAGE login_pkg IS
 FUNCTION login_ck_pf 
  (p_user IN VARCHAR2,
   p_pass IN VARCHAR2)
   RETURN CHAR;
END;
/
CREATE OR REPLACE PACKAGE BODY login_pkg IS
 FUNCTION login_ck_pf 
  (p_user IN VARCHAR2,
   p_pass IN VARCHAR2)
   RETURN CHAR
  IS
   lv_ck_txt CHAR(1) := 'N';
   lv_id_num NUMBER(5);
 BEGIN
   SELECT idShopper
    INTO lv_id_num
    FROM bb_shopper
    WHERE username = p_user
     AND password = p_pass;
   IF SQL%FOUND THEN
     lv_ck_txt := 'Y';
     lv_id_num := lv_id_num;
   END IF;
   RETURN lv_ck_txt;
 EXCEPTION
  WHEN NO_DATA_FOUND THEN
   DBMS_OUTPUT.PUT_LINE('Invalid Login');
   lv_ck_txt := 'N';
   return lv_ck_txt;
 END;
END;
/
show errors;

execute login_pkg.login_ck_pf('gma1', 'goofy');

到目前为止,感谢您的帮助,我现在正在编译它,我只需要弄清楚如何调用它。如果找到该行,我想返回 Y,如果没有找到,我想返回 N。

PACKAGE login_pkg compiled
PACKAGE BODY login_pkg compiled
No Errors.

Error starting at line 35 in command:
execute login_pkg.login_ck_pf('gma1', 'goofy')
Error report:
ORA-06550: line 1, column 7:
PLS-00221: 'LOGIN_CK_PF' is not a procedure or is undefined
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:
4

2 回答 2

5

由于 login_ck_pf 是一个函数而不是一个过程,因此您需要提供一个变量来分配返回值:

DECLARE
    v_ret CHAR(1);
BEGIN
    v_ret := login_pkg.login_ck_pf('gma1','goofy');
    DBMS_OUTPUT.PUT_LINE(v_ret);
END;
/

或者,您可以这样做:

SELECT login_pkg.login_ck_pf('gma1','goofy') FROM dual;
于 2012-04-12T03:50:27.643 回答
4

您需要先创建包规范,然后才能编译您的主体(实现):

CREATE OR REPLACE PACKAGE login_pkg IS

 FUNCTION login_ck_pf 
  (p_user IN VARCHAR2,
   p_pass IN VARCHAR2)
   RETURN CHAR;

END;
/

包规范是您定义要公开以供使用的过程、函数、常量、类型等的签名(接口、api)的地方。包体具有这些定义的实现。规范可以没有主体而存在,但主体不能没有规范而存在。规范中定义的所有内容都必须在正文中实现。您可以在主体中定义额外的过程而不将它们放入规范中,然后这些作为“私有”过程在主体内使用而不可供外部使用。

我想当我们这样做的时候,身体里还有其他一些东西。我没有看到 lv_id_num 或 pv_id_num 在任何地方使用。如果没有找到一行,那么带有“if sql%found”的代码块会被命中还是直接进入异常处理程序?如果调用异常处理程序,您是否想返回一个值“N”?我知道你现在只是在胡闹,所以只是一些想法。

于 2012-04-12T00:57:16.147 回答