본문 바로가기

DB

Oracle PL/SQL 프로시저 [패키지]

반응형

논리적 연관성이 있는 PL/SQL 타입,변수,상수,서브 프로그램 ,커서 예외 등의 항목을 묶어 놓은 객체다. 패키지란 말은 '포장' 이란 뜻인데, 오라클에서 말하는 패키지 역시 PL/SQL 구성요소, 서브 프로그램들을 불러 모아 하나의 이름으로 묶어 놓은 객체라고 보면 된다.

 

모듈화 기능

패키지의 가장 큰 장점은 모듈화가 가능하다는 점이다. 패키지는 여러 함수나 프로시저를 묶어 놓은 객체다. 즉 업무적으로 연관성이 있거나 비슷한 기능을 수행하는 서브 프로그램이나 변수,상수,커서, 사용자 정의 타입들을 하나의 패키지에 담아두면 이해 하기도, 관리하기도 쉽다.

 

캡슐화

캡슐화란 꼭 필요한 부분만 외부에 공개하고 그외 세부 로직은 접근을 차단한다는 개념이다.

패키지 선언부는 외부에 공개되지만 패캐지에 속한 커서,함수,프로시저의 세부 구현 내용이 담겨 있는 본문 부분은 외부에서는 볼수 없다.

 

성능

패키지에 있는 서브 프로그램을 호출하면 일단 해당 패키지 전체를 메모리에 올려 놓는데 이후 계속 호출하더라도 메모리에 올라가 있는 상태이므로 더 좋은 성능을 보인다.

 

 

패키지 구조

패키지 선언부

선언부는 패키지에서 사용할 사용자의 정의 타입, 변수,상수,예외 그리고 서브 프로그램의 골격을 선언해 놓는 부분으로 그 구문은 다음과 같다.

 CREATE OR REPLACE PACKAGE 패키지명 
 IS
 TYPE_구문;
 상수명 CONSTANT 상수_타입;
 예와명 EXCEPTION;
 변수명 변수_타입;
 커서 구문;
 
 FUNCTION 함수명 (매개변수 1 IN 매개변수1_타입,
 					매개변수2 IN 매개변수2_타입, )
                    
                    RETURN
                    
 PROCEDURE 프로시저명 (매개변수 1 IN 매개변수1_타입,
 				    매개변수2 IN 매개변수2_타입, );
                                        
 END;

선언부는 크게 데이터와 서브 프로그램 영역으로 나눌 수 있다.

서브 프로그램에는 함수와 프로시저가 있는데, 패키지 선언부에서는 이 두 객체의 명세,즉 서브 프로그램명과 매개변수를 명시한다. (사용하려는 함수나 프로시저에 대해 프로그램명, 매개변수 개수와 타입, 반환타입)을 참조할수 있다.

 

 

본문 구문

CREATE OR REPLACE PACKAGE BODY 패키지명 IS
상수명 CONSTANT 상수_타입;
변수명 변수타입;
커서 정의 구문;
	FUNCTION(매개변수1 IN 매개변수1_타입,
    			매개변수2 IN 매개변수2_타입)
                RETURN 반환 타입 IS
                
                IS
                ..
                BEGIN
                ..
                END 함수명;
                
                PROCEDURE 프로시저명(매개변수1 [IN,OUT,IN OUT] 매개변수1_타입,
                					매개변수1 [IN,OUT,IN OUT] 매개변수1_타입)
                                    
                                    IS
                                    ..
                                    BEGIN
                                    ..
                                    END 프로시저명;
                                    END;

선언부에서와 마찬가지로 상수, 변수, 등을 선언할수 있다. 패키지 본문에서 선언한 상수나 변수는 외부에서 참조할수 없다. 그리고 선언부에서 커서나 서브 프로그램을 선언했면 이들의 세부적인 구현 부분은 패키지 본문에서 작성한다. 패키지 본문내용은 패키지 작성자만 접근해 수정할수 있으며, 다른 사용자는 전혀 볼 수가 없다.

 

CREATE OR REPLACE PACKAGE EMP_PKG
   IS
   --사번을 받아 이름을 반환하는 함수
   FUNCTION FN_EMP_NAME(PN_EMPLOYEE_ID IN NUMBER)
     --신규 사원 등록
   PROCEDURE NEW_EMPLOYEE_PROC(PS_EMPLOYEE_NAME IN VARCHAR2 , PD_HIRE_DATE IN VARCHAR2);
   --퇴사 사원 등록
   PROCEDURE RETIRE_EMP_PROC(PN_EMPLOYEE_ID IN NUMBER);
   END EMP_PKG;

선언부만 작성해도 컴파일이 되었다. 

 

CREATE OR REPLACE PACKAGE HR_PKG
IS
FUNCTION FN_EMP_NAME(PN_EMPLOYEE_ID IN NUMBER)
  RETURN VARCHAR2
  VS_EMP_NAME EMPLOYEES.EMP_NAME %TYPE;
  BEGIN
    SELECT EMP_NAME
    INTO VS_EMP_NAME
    FROM EMPLOYEES
    WHERE EMPLOYEE_ID = PN_EMPLOYEE_ID;
    RETURN NVL(VS_EMP_NAME ,'해당사원없음');
    END FN_EMP_NAME;
    
    PROCEDURE NEW_EMP_PROC(PS_EMP_NAME IN VARCHAR2,
                           PS_HIRE_DATE IN VARCHAR2)
    IS
    
    VN_EMP_ID EMPLOYEES.EMPLOYEE_ID %TYPE;
    VN_HIRE_DATE DATE := TO_DATE(PS_HIRE_DATE,'YYYY-MM-DD');
    BEGIN
      SELECT NVL(MAX(EMPLOYEE_ID),0)+1;
      INTO VN_EMP_ID
      FROM INSERT INTO EMPLOYEES
           (EMPLOYEE_ID,EMP_NAME,HIRE_DATE,CREATE_DATE,UPDATE_DATE)
           VALUES(VN_EMP_ID,PS_EMP_NAME,NVL(HIRE_DATE,SYSDATE),SYSDATE,SYSDATE);
           COMMIT;
           END NEW_EMP_PROC;
           
           
    PROCEDURE RETIRE_EMP_PROC(PN_EMPLOYEE_ID IN NUMBER)
    IS
    VN_CNT NUMBER := 0;
    E_NO_DATE EXCEPTION;
    BEGIN
              UPDATE EMPLOYEES
              SET RETIRE_DATE = SYSDATE
              WHERE EMPLOYEE_IS = PN_EMPLOYEE_ID
              AND RETIRE_DATE NULL;
              VN_CNT := SQL%ROWCOUNT;
              
              IF VN_CNT = 0 THEN
                RAISE E_NO_DATA;
                END IF;
                COMMIT;
                
                EXCEPTION WHEN E_NO_DATA THEN
                  DBMS_OUTPUT.PUT_LINE(PN_EMPLOYEE_ID ||'해당되는 퇴사처리할 사원이 없다');
                  ROLLBACK;
                  WHEN OTHERS THEN
                    DBMS_PUTPUT.PUT_LINE(SQLERRM);
                    ROLLBACK;
                    
                    END RETIRE_EMP_PROC;
           END HR_PKG;

패키지 본문 역시 성공적으로 컴파일 됬다. 

 

 

패키지 데이터

 

프로시저 내에서 변수나, 커서, 레코드 등은 패키지 본문의 구현부에서 직접 정의해 사용할 수 있으므로 굳이 패키지에 데이터를 담아둘 필요는 없다. 

성수와 변수 선언

패키지 안에 상수나 변수를 선언하게 되면 이들의 생존 주기는 세션단위로 한 세션이 살아 있는 동안에는 그 값이 메모리상에 유지 된다. 상수는 값이 일정하니 유지되고 말고도 없겠지만, 변수는 해당 패키지의 사용이 끝낫더라도 같은 세션에서는 그 값을 공유한다.

 

CREATE OR REPLACE  PACKAGE PA_CONST
  
  IS
  C_TEST CONSTANT VARCHAR2(10) := 'TEST';
  
  V_TSET VARCHAR2(10);
  
  END;
  /
  
    BEGIN
    DBMS_OUTPUT.PUT_LINE('C_TEST : ' ||PA_CONST.C_TEST);
    DBMS_OUTPUT.PUT_LINE('V_TSET : ' ||PA_CONST.V_TSET);
    END;
  

PA_CONST.V_TEST 값은 NULL임을 알수 있다. 

변수값을 변경하게 되면 

 

BEGIN
    DBMS_OUTPUT.PUT_LINE('C_TEST : ' ||PA_CONST.V_TEST);
    PA_CONST.V_TSET
    DBMS_OUTPUT.PUT_LINE('V_TSET : ' ||PA_CONST.V_TSET);
    END;

패키징서 선언한 변수에는 두가지 중요한 특징이 있다. 위 예제처럼 패키지 선언부에 선언한 변수는 외부에서 접근하고 수정할수 있는데, 이를 공용항목 이라고도 한다. 이렇게 패키지에서 선언한 변수는 그 값이 세션이 살아 있는 동안 유지 된다.

 

 

반응형