(3)PL/SQL PROCEDURE

PL/SQL의 PROCEDURE 사용법


시작하기 전에

사용 교재 : 오라클SQL과 PL/SQL을 다루는 기술 (https://thebook.io/006696/)

예제 코드 : https://github.com/gilbutITbook/006696


SERVEROUTPUT 설정

PL/SQL 결과물을 보기 위해 아래의 실행문을 실행

SET SERVEROUTPUT ON;

PL/SQL PROCEDURE

사용자 정의 함수는 특정 연산을 수행한 뒤 결과 값을 반환하지만,

프로시저는 특정한 로직을 처리하기만 하고 값을 반환하지는 않는 서브 프로그램이다.


PROCEDURE 기본 구조

CREATE OR REPLACE PROCEDURE 프로시저 이름(
   매개변수명1 [IN | OUT | IN OUT] 테이터타입 [:= 디폴트 ],

                          :
                          :

	 매개변수명n [IN | OUT | IN OUT] 테이터타입 [:= 디폴트 ]
)

IS[AS]
	변수, 상수  선언

BEGIN
	실행부

[EXCEPTION]
	예외처리

END [프로시저 이름];
  • []는 생략 가능

PROCEDURE 예제


예제1

  • jobs 테이블에 신규 JOB을 넣는 프로시저
-- my_new_job_proc 프로시저 신규생성
CREATE OR REPLACE PROCEDURE my_new_job_proc(
            p_job_id    IN JOBS.JOB_ID%TYPE,
            p_job_title IN JOBS.JOB_TITLE%TYPE,
            p_min_sal   IN JOBS.MIN_SALARY%TYPE,
            p_max_sal   IN JOBS.MAX_SALARY%TYPE )
IS

BEGIN
	INSERT INTO JOBS (
                              job_id,
                              job_title,
                              min_salary,
                              max_salary,
                              create_date,
                              update_date)
	          VALUES (  
                            p_job_id,
                            p_job_title, 
                            p_min_sal, 
                            p_max_sal, 
                            SYSDATE, 
                            SYSDATE);
	COMMIT;
	
END;
/

-- 프로시저 실행
EXEC my_new_job_proc('SM_JOB1', 'Sample JOB1', 1000, 5000);

-- 프로시저 결과
select * from jobs;

1


예제2


  • 예제 1을 수정
    • 데이터가 있을 경우 INSERT / 없을 경우 UPDATE
-- my_new_job_proc 프로시저 수정
CREATE OR REPLACE PROCEDURE my_new_job_proc(
            p_job_id    IN JOBS.JOB_ID%TYPE,
            p_job_title IN JOBS.JOB_TITLE%TYPE,
            p_min_sal   IN JOBS.MIN_SALARY%TYPE,
            p_max_sal   IN JOBS.MAX_SALARY%TYPE 
)
IS
    vn_cnt NUMBER := 0;
    
BEGIN
    -- job id를 통해 데이터의 유뮤를 파악함
    SELECT COUNT(*) INTO vn_cnt
    FROM jobs
    WHERE job_id = p_job_id;
    
    -- cnt가0 이다 -> 데이터가 없다 -> INSERT
	IF vn_cnt = 0 THEN
        INSERT INTO JOBS ( job_id, job_title, min_salary, max_salary, create_date, update_date)
        VALUES ( p_job_id, p_job_title, p_min_sal, p_max_sal, SYSDATE, SYSDATE);   
    
    -- cnt가 0이 아님 -> 데이터가 있다 -> UPDATE
    ELSE
        UPDATE jobs
        SET job_title = p_job_title,
             min_salary = p_min_sal,
             max_salary = p_max_sal,
             update_date = SYSDATE
        WHERE job_id = p_job_id;
        
    END IF;
    
    COMMIT;

END;
/

-- 프로시저 실행 (UPDATE)
EXEC my_new_job_proc('SM_JOB1', 'Sample JOB1', 1500, 5000);

-- 프로시저 결과
select * from jobs;

2

  • 기존의 SM_JOB1의 MIN_SALARY가 1500으로 UPDATE


-- 프로시저 실행 (INSERT)
EXEC my_new_job_proc('SM_JOB2', 'Sample JOB2', 2000, 6000);

-- 프로시저 결과
select * from jobs;

3

  • SM_JOB2는 기존에 있는 데이터가 아니므로 INSERT


예제3

  • 예제2를 수정
    • 프로시저를 실행할 때 디폴트 값을 주어, 매개변수를 입력하지 않아도 실행되게 변경
    • **<주의> IN 매개변수에만 사용 가능**
-- my_new_job_proc 프로시저 수정 
CREATE OR REPLACE PROCEDURE my_new_job_proc(
            p_job_id    IN JOBS.JOB_ID%TYPE,
            p_job_title IN JOBS.JOB_TITLE%TYPE,
      
            -- 디폴트 값 주기
            p_min_sal   IN JOBS.MIN_SALARY%TYPE := 10,
            p_max_sal   IN JOBS.MAX_SALARY%TYPE := 1000
)

-- 아랫부분은 동일

-- 프로시저 실행
EXEC my_new_job_proc('SM_JOB3', 'Sample JOB3');

-- 프로시저 결과
select * from jobs;

4

  • 매개변수 없이 프로시저를 실행했지만, 세팅해놓은 디폴트 값 10, 1000이 자동으로 입력

PROCEDURE - IN , OUT, IN OUT

프로시저는 값을 반환하지 않는 서브 프로그램이지만, 값을 반환하는 방법이 존재 - OUT 매개변수


IN, OUT, IN OUT 예제


  • 프로시저 생성
-- my_parameter_test_proc 신규 생성
CREATE OR REPLACE PROCEDURE my_parameter_test_proc (
               -- IN : 값을 받기만 함
               p_var1        VARCHAR2,

               -- OUT : 값을 반환
               p_var2 OUT    VARCHAR2,

               -- IN OUT : 값을 받고 반환함
               p_var3 IN OUT VARCHAR2 )
IS

BEGIN
	 DBMS_OUTPUT.PUT_LINE('p_var1 value = ' || p_var1);
	 DBMS_OUTPUT.PUT_LINE('p_var2 value = ' || p_var2);
	 DBMS_OUTPUT.PUT_LINE('p_var3 value = ' || p_var3);
	 
   p_var2 := 'A2';
	 p_var2 := 'B2';
	 p_var3 := 'C2';
	
END;
/


  • 익명블록으로 테스트
DECLARE 
   v_var1 VARCHAR2(10) := 'A';
   v_var2 VARCHAR2(10) := 'B';
   v_var3 VARCHAR2(10) := 'C';
BEGIN
   -- (1)프로시저 호출
	 my_parameter_test_proc (v_var1, v_var2, v_var3);
	 
   -- (2)프로시저 호출 후 값 비교
   DBMS_OUTPUT.PUT_LINE('v_var1 value = ' || v_var1);
	 DBMS_OUTPUT.PUT_LINE('v_var2 value = ' || v_var2);
	 DBMS_OUTPUT.PUT_LINE('v_var3 value = ' || v_var3);
END;
/

5

p_var1은 IN이므로 A가 저장 및 실행

p_var2는 OUT이므로 B가 저장 되지 않고 실행 후 B2를 반환

p_var3은 IN OUT이므로 C를 저장하고 실행 후 C2를 반환

-------------------------------------------

v_var1은 반환되어진 A가 아니라, 원래 선언해두었던 A를 표시

v_var2는 반환된 B2 표시

v_var3은 반환된 C2 표시


PROCEDURE RETURN

사용자 정의 함수에서의 RETURN은 값을 반환하는 역할이지만

프로시저에서의 RETURN은 수행을 종료하는 역할을 한다


PROCEDURE RETURN 예제

  • PROCEDURE 예제 수정
CREATE OR REPLACE PROCEDURE my_new_job_proc(
				...
)
...
BEGIN
    -- 1000보다 작으면 메시지 출력 후 RETURN
    IF p_min_sal <1000 THEN
        DBMS_OUTPUT.PUT_LINE('최소 급여값은 1000 이상이어야 함');
        RETURN;
    END IF;

		SELECT COUNT(*)
    ...
		...

...

-- 프로시저 실행 : 1000보다 작은 값
EXEC my_new_job_proc('SM_JOB4', 'Sample JOB4', 999, 50000);

-- 프로시저 결과
select * from jobs;

6

7

  • 프로시저는 완료되지만 ‘SM_JOB4’는 저장되지 않는다.






Categories:

Updated:

Leave a comment