PLSQL文档是否说明了子程序在包中的顺序?

时间:2016-12-05 23:28:31

标签: oracle function plsql package procedure

我正在编写一个包含许多函数和过程的包来处理HR表。但我不确定是否有关于子程序顺序的考虑。如果您编译一个包然后在现有包的中间创建一个新过程会发生什么?感谢。

CREATE OR REPLACE PACKAGE BODY empinfo_pkg IS

  FUNCTION emp_sal_1(
    p_empid employees.employee_id%TYPE,
    p_sal   employees.salary%TYPE)
  RETURN NUMBER
  IS
    v_incre_sal NUMBER(8,2);
  BEGIN
    SELECT SALARY * p_sal
    INTO   v_incre_sal
    FROM   employees
    WHERE  employee_id = p_empid;
    RETURN v_incre_sal;
  END emp_sal_1;

  PROCEDURE emp_basicinfo_1(
    p_empid employees.employee_id%TYPE)
  IS
    v_info VARCHAR2(200);
  BEGIN
    SELECT employee_id || ' ' || first_name || ' ' || last_name
    INTO   v_info
    FROM   employees
    WHERE  employee_id = p_empid;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      DBMS_OUTPUT.PUT_LINE('NO EXISTE EMPLEADO CON ID INGRESADO');
  END emp_basicinfo_1;

  FUNCTION emp_comm_1(
    p_empid employees.employee_id%TYPE)
  RETURN NUMBER
  IS
    v_comm NUMBER(8,2);
  BEGIN
    SELECT commission_pct
    INTO   v_comm
    FROM   employees
    WHERE  employee_id = p_empid;
    RETURN v_comm;
  END emp_comm_1;

  PROCEDURE emp_allinfo_1(
    p_empid  IN  employees.employee_id%TYPE,
    p_refcur OUT SYS_REFCURSOR)
  IS
  BEGIN
    OPEN p_refcur
    FOR SELECT *
    FROM       employees
    WHERE      employee_id = p_empid;
  END emp_allinfo_1;

END empinfo_pkg;
/
SHOW ERRORS;

1 个答案:

答案 0 :(得分:4)

除了在调用其他方法之前提供签名之外,Oracle不关心您声明程序的顺序。这可以通过将方法设置为public并在包规范中声明它,在调用包之前在包体中创建前向声明,或者在调用方法之前定义方法来完成。

假设我想要一个从empinfo_pkg内写入日志表的方法。我可以在包规范中声明该方法,但这可能没有意义。包外的调用者永远不会想要调用此日志记录方法,因为它特定于记录与员工相关的事物。我可以在第一次使用之前定义包中的程序,即

  PROCEDURE log_employee_action( p_empid IN  employees.employee_id%TYPE,
                                 p_action IN varchar2(10))
  AS
  BEGIN
    <<do some logging>>
  END;

  PROCEDURE emp_allinfo_1(
    p_empid  IN  employees.employee_id%TYPE,
    p_refcur OUT SYS_REFCURSOR)
  IS
  BEGIN
    log_employee_action( p_empid, 'SELECT' );

    OPEN p_refcur
    FOR SELECT *
    FROM       employees
    WHERE      employee_id = p_empid;
  END emp_allinfo_1;

或者我可以创建一个前向声明并在以后定义

  -- A forward declaration with no implementation
  PROCEDURE log_employee_action( p_empid IN  employees.employee_id%TYPE,
                                 p_action IN varchar2(10));

  PROCEDURE emp_allinfo_1(
    p_empid  IN  employees.employee_id%TYPE,
    p_refcur OUT SYS_REFCURSOR)
  IS
  BEGIN
    log_employee_action( p_empid, 'SELECT' );

    OPEN p_refcur
    FOR SELECT *
    FROM       employees
    WHERE      employee_id = p_empid;
  END emp_allinfo_1;

  -- And an implementation later
  PROCEDURE log_employee_action( p_empid IN  employees.employee_id%TYPE,
                                 p_action IN varchar2(10))
  AS
  BEGIN
    <<write to log table>>
  END;

虽然甲骨文并不太关心宣布订单的内容,但如果按照合理的逻辑顺序声明事情,未来的开发人员可能会很感激。例如,如果您要从许多不同的过程调用实用程序函数,那么首先声明它们而不是创建前向声明并在整个代码中随意实现这些实用程序方法可能是有意义的。以某种逻辑方式将方法组合在一起可能是有意义的。例如,如果你有一堆set_<<some attribute>>程序,将它们放在一起而不是在整个程序包中都有它们可能是有意义的。 Oracle不会关心,但是如果开发人员试图找出定义set_first_nameset_last_name的位置,那么如果他们相互接近,就会很感激。