【问题标题】:Does the PLSQL documentation say anything about order of subprograms into a package?PLSQL 文档是否说明了关于子程序进入包的顺序?
【发布时间】:2017-04-20 11:54:04
【问题描述】:

我正在编写一个包含许多功能和过程的程序包来处理 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;

【问题讨论】:

    标签: oracle function plsql package procedure


    【解决方案1】:

    Oracle 不关心您声明过程的顺序,除了您在调用另一个方法之前提供签名。这可以通过将方法公开并在包规范中声明,在调用之前在包主体中创建前向声明,或在调用之前定义方法来完成。

    假设我想要一个从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;
    

    虽然 Oracle 不太关心事物的声明顺序,但如果事物以合理的逻辑顺序声明,未来的开发人员可能会喜欢它。例如,如果您有将要从许多不同的过程调用的实用程序函数,那么首先声明它们而不是创建前向声明并在整个代码中随意实现这些实用程序方法可能是有意义的。以某种逻辑方式将方法组合在一起可能是有意义的。例如,如果您有一堆set_&lt;&lt;some attribute&gt;&gt; 过程,那么将它们放在一起而不是将它们全部放在整个包中可能是有意义的。 Oracle 不会在意,但如果开发人员试图找出 set_first_nameset_last_name 的定义位置,如果它们彼此相当接近,他们会很感激。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-31
      • 1970-01-01
      • 1970-01-01
      • 2021-06-05
      • 1970-01-01
      相关资源
      最近更新 更多