2016-12-05 57 views
0

我正在编写一个包含许多功能和程序的软件包来处理HR表。但我不确定是否有任何关于子程序顺序的考虑。如果你编译一个包,然后在现有包的中间创建一个新过程,会发生什么?谢谢。PLSQL文档是否对子程序的顺序进行了说明?

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; 

回答

4

在调用另一个方法之前,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; 

如果事情以合理的逻辑顺序进行声明,那么未来的开发人员可能会赞赏它。例如,如果您有许多不同的过程调用的效用函数,那么首先声明这些函数可能是有意义的,而不是创建前向声明并在整个代码中随意实现这些实用程序方法。以某种逻辑方式将方法组合在一起可能是有意义的。例如,如果你有一堆set_<<some attribute>>程序,将它们放在一起而不是将它们放在整个程序包中可能是有意义的。甲骨文不会在乎,但是一个试图找出set_first_nameset_last_name被定义在哪里的开发人员,如果他们彼此相当接近,他们会很感激。

+0

感谢您的帮助! – Rattlesnake