IT기술/Oracle

16 PL/SQL 제어문

dobbby 2013. 11. 15. 17:54
반응형

오라클이 제공하는 제어문의 종류는 크게 조건문과 반복문으로 나눌 수 있다.

조건문은 IF 문과 CASE 문이 있으며 반복문은 반복횟수를 알 수 없을 경우에 주로 사용하는 BASIC LOOP 문장과 WHILE 문 

그리고 반복횟수를 지정할 수 있는 FOR 문으로 나눌 수있다.


1. 조건문(IF 문)


유형1. IF ~ END IF 문장


예: EMP 테이블에서 EMPNO, ENAME, DEPTNO, DNAME 을 출력하세요.

단, DNAME 의 값은 아래와 같습니다.

DEPTNO 가 10이면 'ACCOUNT'

DEPTNO 가 20이면 'RESEARCH'

DEPTNO 가 30이면 'SALES'

DEPTNO 가 40이면 'OPERATIONS'


SET SERVEROUTPUT ON


DECLARE

v_empno emp.empno%TYPE ;

v_ename emp.ename%TYPE ;

v_deptno emp.deptno%TYPE ;

v_dname VARCHAR2(20) := null ;


BEGIN

SELECT    empno, ename, deptno

INTO        v_empno, v_ename, v_deptno

FROM        emp

WHERE        empno = 7900 ;


IF (v_deptno = 10) THEN

v_dname := 'ACCOUNT' ;

END IF ;

IF (v_deptno = 20) THEN

v_dname := 'RESEARCH' ;

END IF ;

IF (v_deptno = 30) THEN

v_dname := 'SALES' ;

END IF ;

IF (v_deptno = 40) THEN

v_dname := 'OPERATIONS' ;

END IF ;


DBMS_OUTPUT.PUT_LINE (v_empno||' '||v_ename||' '||v_deptno||' '||v_dname) ;


END ;

/


 유형2. IF ~ THEN ELSIF ~THEN END IF 문장 (조건이 여러개일 경우 사용)


예. 위의 문제를 다시 풀어보겠다.


DECLARE

v_empno emp.empno%TYPE ;

v_ename emp.ename%TYPE ;

v_deptno emp.deptno%TYPE ;

v_dname VARCHAR2(20) := null ;


BEGIN

SELECT    empno, ename, deptno

INTO        v_empno, v_ename, v_deptno

FROM        emp

WHERE        empno = 7900 ;


IF (v_deptno = 10) THEN

v_dname := 'ACCOUNT' ;

ELSIF (v_deptno = 20) THEN

v_dname := 'RESEARCH' ;

ELSIF (v_deptno = 30) THEN

v_dname := 'SALES' ;

ELSIF (v_deptno = 40) THEN

v_dname := 'OPERATIONS' ;

END IF ;


DBMS_OUTPUT.PUT_LINE (v_empno||' '||v_ename||' '||v_deptno||' '||v_dname) ;


END ;

/


유형3. IF ~ THEN ELSE END IF (조건이 2개일 경우)


예. EMP 테이블에서 사원번호가 7900 번인 사원의 EMPNO, ENAME, COMM 을 출력하되 해당 사원의 COMM 이 0보다 크면 COMM 의 금액을 출력하고, 0보다 작으면 '사원의 보너스는 없습니다' 라는 문장을 출력하세요.


DECLARE

v_empno emp.empno%TYPE ;

v_ename emp.ename%TYPE ;

v_comm emp.comm%TYPE := null ;


BEGIN

SELECT    empno, ename, comm

INTO        v_empno, v_ename, v_comm

FROM        emp

WHERE        empno = 7900 ;


IF v_comm > 0 THEN

DBMS_OUTPUT.PUT_LINE (v_ename||' 사원의 보너스는 '||v_comm||' 입니다. ') ;

ELSE

DBMS_OUTPUT.PUT_LINE (v_ename||' 사원의 보너스는 없습니다. ') ;

END IF ;

END ;

/


연습문제1. 사용자로부터 사원번호를 입력받아 해당 사원의 보너스가 0보다 클 경우 보너스 금액을 출력하고, 0보다 작을 경우 '보너스가 없습니다' 라는 문장을 출력하세요. 조건이 2가지이므로 IF THEN ELSE END IF 문장을 사용하세요.


DECLARE

v_empno emp.empno%TYPE ;

v_ename emp.ename%TYPE ;

v_comm emp.comm%TYPE := null ;


BEGIN

SELECT    empno, ename, comm

INTO        v_empno, v_ename, v_comm

FROM        emp

WHERE        empno = '&empno' ;


IF v_comm > 0 THEN

DBMS_OUTPUT.PUT_LINE (v_ename||' 사원의 보너스는 '||v_comm||' 입니다.') ;

ELSE

DBMS_OUTPUT.PUT_LINE (v_ename||' 사원의 보너스는 없습니다.') ;

END IF ;

END ;

/


연습문제2. 사번을 입력받아 해당 사원의 이름과 연봉, 세금을 출력하세요.

단, 세금은 연봉액수에 따라 5000만원 이상이면 5%,

4000만원 이상 4999만원 이하 4%,

3000만원 이상 3999만원 이하 3%,

2000만원 이상 2999만원 이하 2%,

나머지는 1% 로 차등계산한다.

조건이 여러가지 이므로 IF THEN ELSIF ELSE END IF 문장을 사용하세요.


DECLARE

v_empno emp.empno%TYPE := &eno ;

v_ename emp.ename%TYPE ;

v_sal emp.sal%TYPE ;

v_tax NUMBER ;


BEGIN

SELECT    empno, ename, sal

INTO        v_empno, v_ename, v_sal

FROM        emp

WHERE    empno = v_empno ;


IF v_sal >= 5000 THEN

v_tax := v_sal * 0.05 ;

ELSIF v_sal BETWEEN 4000 AND 4999 THEN

v_tax := v_sal * 0.04 ;

ELSIF v_sal BETWEEN 3000 AND 3999 THEN

v_tax := v_sal * 0.03 ;

ELSIF v_sal BETWEEN 2000 AND 2999 THEN

v_tax := v_sal * 0.02 ;

ELSE

v_tax := v_sal * 0.01 ;

END IF ;


DBMS_OUTPUT.PUT_LINE ( '사번'||' '||'이름'||' '||'연봉'||' '||'세금') ;

DBMS_OUTPUT.PUT_LINE ( v_empno||' '||v_ename||' '||v_sal||' '||v_tax) ;

END ;

/


2. CASE 문과  CASE 식

조건이 여러가지 일 경우 IF문보다 더 간결하게 작성할 수 있는 제어문

문법

CASE [조건]

WHEN 조건 1 THEN 결과1

WHEN 조건 2 THEN 결과2

...

WHEN 조건 n THEN 결과n

[ELSE 기본값]

END ;


CASE 내부의 여러 조건들을 구분할 때 (콤마)를 사용하지 않고, 

ELSE 기본값은 없으면 생략 가능하며,

CASE 로 시작한 후 해당 문장을 끝낼 때는 반드시 END 키워드를 사용해야 한다.


CASE 문 사용 예1. 사용자로부터 사원번호를 입력받은 후 EMP 테이블에서 EMPNO, ENAME, DEPTNO, DNAME 을 출력하세요.

단, DNAME 의 값은 아래와 같습니다.

DEPTNO 가 10이면 'ACCOUNT'

DEPTNO 가 20이면 'RESEARCH'

DEPTNO 가 30이면 'SALES'

DEPTNO 가 40이면 'OPERATIONS'


DECLARE

v_empno emp.empno%TYPE ;

v_ename emp.ename%TYPE ;

v_deptno emp.deptno%TYPE ;

v_dname VARCHAR2(10) ;


BEGIN

SELECT    empno, ename, deptno

INTO        v_empno, v_ename, v_deptno

FROM        emp

WHERE        empno = '&empno' ;

v_dname := CASE v_deptno

WHEN 10 THEN 'ACCOUNT' 

WHEN 20 THEN 'RESEARCH

WHEN 30 THEN 'SALES

WHEN 40 THEN 'OPERATIONS

END ;

DBMS_OUTPUT.PUT_LINE (v_empno||' '||v_ename||' '||v_deptno||' '||v_dname) ;

END ;

/


CASE 문 사용 예2. 사용자로부터 사원번호를 입력받은 후 EMP 테이블에서 EMPNO, ENAME, SAL, DEPTNO, 인상 후 연봉(UPSAL) 을 출력하세요.

단, 부서번호가 10번 부서는 현재 연봉의 10% 인상하고,

부서번호가 20번, 30번 부서는 현재 연봉의 20% 인상하고,

부서번호가 30번보다 클 경우 30% 인상하세요.


DECLARE

v_empno emp.empno%TYPE ;

v_ename emp.ename%TYPE ;

v_sal emp.sal%TYPE ;

v_deptno emp.deptno%TYPE ;

v_up_sal emp.sal%TYPE ;


BEGIN

SELECT    empno, ename, sal, deptno

INTO        v_empno, v_ename, v_sal, v_deptno

FROM        emp

WHERE        empno = '&empno' ;

v_up_sal := CASE

WHEN v_deptno = 10 THEN v_sal * 1.1 

WHEN v_deptno IN (20, 30) THEN v_sal * 1.2 

WHEN v_deptno > 30 THEN v_sal * 1.3 

ELSE v_sal

END ;

DBMS_OUTPUT.PUT_LINE ('사원번호'||' '||'이름'||' '||'급여'||' '||'부서번호'||' '||'인상 후 급여') ;

DBMS_OUTPUT.PUT_LINE (v_empno||' '||v_ename||' '||v_sal||' '||v_deptno||' '||v_up_sal) ;

END ;

/


CASE 문과 CASE 식은 다르다.

CASE 식은 CASE 문장 내부에 있는 조건에 따라 값을 반환하는 것으로 끝난다. 끝은 END ; 

CASE 문은 CASE 문자 내부의 조건에 따라 정해진 작업을 수행한다. 끝은 END CASE ;





[출처] 다양한 예제로 쉽게 배우는 오라클 SQL과 PL/SQL 서진수 저



반응형