我正在编写一个包含许多函数和过程的包来处理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;
答案 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_name
和set_last_name
的位置,那么如果他们相互接近,就会很感激。