본문 바로가기

Database/PLSQL

053 - [Oracle PL/SQL] Package - Forward Declaration

<샘플코드에서 사용한 데이터는 HR 스키마이고, 오라클 설치시 생성할 수 있는 기본 스키마 입니다>

 

 

 

 

 

 

 

 

 

보통은 선언부에 선언을 먼저하기 때문에 바디에서 정의하는 순서는 문제가 되지 않는다.

 

아래 샘플은 선언부에 선언하지 않았지만 오류가 발생하지 않는다, 이유는 

본문/바디에 정의할때, 호출되는 함수(get_no_work_days)나 패키지를 호출하는 패키지나 함수 앞에 정의했기 때문이다.

 

 

create or replace package proc_rules_calling
is
    procedure print_emp_details 
    (p_emp_id number);
--    function get_no_work_days (p_emp_id number) return number;
end;
/

create or replace package body proc_rules_calling
is
    function get_no_work_days (p_emp_id number)
        return number
    is
        v_hiredate date;
    begin
        select HIRE_DATE into v_hiredate
        from employees
        where EMPLOYEE_ID=p_emp_id;
        return round(sysdate-v_hiredate);
    end;

    procedure print_emp_details 
        (p_emp_id number)
    is
    -- we will call the funcion from this procedure
    --so it should be defined above in order to invoke it
        v_details employees%rowtype;
    begin
        select * into v_details
        from employees
        where EMPLOYEE_ID=p_emp_id;
        dbms_output.put_line( 'id:'||v_details.EMPLOYEE_ID);
        dbms_output.put_line( 'fname:'||v_details.FIRST_NAME);
        dbms_output.put_line( 'salary:'||v_details.salary);
        dbms_output.put_line( 'hire date:'||v_details.HIRE_DATE);
        dbms_output.put_line( 'no of days work:'||get_no_work_days(p_emp_id));
    end;
end;

 

 

 

실행결과는 아래와 같다.

 

id:101
fname:Neena
salary:17000
hire date:21-SEP-05
no of days work:6735

 

 

 

이번에는 본문에서 정의할때 순서를 바꿔서 오류가 나도록 만들어 보자.

 

create or replace package proc_rules_calling
is
    procedure print_emp_details 
    (p_emp_id number);
--    function get_no_work_days (p_emp_id number) return number;
end;
/
--it will give error
--'GET_NO_WORK_DAYS' not declared in this scope
create or replace package body proc_rules_calling
is
    procedure print_emp_details 
        (p_emp_id number)
    is
        v_details employees%rowtype;
    begin
        select * into v_details
        from employees
        where EMPLOYEE_ID=p_emp_id;

        dbms_output.put_line( 'id:'||v_details.EMPLOYEE_ID);
        dbms_output.put_line( 'fname:'||v_details.FIRST_NAME);
        dbms_output.put_line( 'salary:'||v_details.salary);
        dbms_output.put_line( 'hire date:'||v_details.HIRE_DATE);
        dbms_output.put_line( 'no of days work:'||get_no_work_days(p_emp_id));
    end;
 
    function get_no_work_days (p_emp_id number) # 정의를 패키지 뒤로 옮겼다.
        return number
    is
        v_hiredate date;
    begin
        select HIRE_DATE into v_hiredate
        from employees
        where EMPLOYEE_ID=p_emp_id;

        return round(sysdate-v_hiredate);
    end;
 
end;

 

 

 

# 오류가 아래처럼 발생한다.

LINE/COL  ERROR
--------- -------------------------------------------------------------
16/9      PL/SQL: Statement ignored
16/51     PLS-00313: 'GET_NO_WORK_DAYS' not declared in this scope
Errors: check compiler log

 

 

 

오류를 해결하는 방법은 선언부를 아래와 같이 변경하면 됩니다.

 

create or replace package proc_rules_calling
is
    procedure print_emp_details 
    (p_emp_id number);
    function get_no_work_days (p_emp_id number) return number;
end;