SQL LOOP문 & EXIT문 & 예외 처리

YeHee·2024년 11월 1일

⏰ 2024.10.31 (D+16)

1. LOOP문

조건식 ⭐]

LOOP
	statement1;
	statement2;
	EXIT [WHEN condition];
END LOOP;

ACCEPT NUM PROMPT '숫자를 입력하세요?'
DECLARE
	HAP NUMBER :=0;
	MYNUM NUMBER := #
BEGIN
	LOOP
		HAP := HAP +MYNUM;
		MYNUM := MYNUM-1;
		EXIT WHEN MYNUM=0;
END LOOP;
	DBMS_OUTPUT.PUT_LINE(&NUM || '까지의 누적합:' || HAP);
END;
/

❗스크립트 활성화
SET SERVEROUTPUT ON

✔️스크립트 활성화 확인
SHOW SERVEROUT

예시 1 📖]

BEGIN
    FOR i IN REVERSE 10 .. 10 LOOP
        DBMS_OUTPUT.PUT_LINE(i);
    END LOOP;

END;
/

예시 2 📖]

ACCEPT NUM PROMPT 'INPUT NUMBER?'

DECLARE
    HAP NUMBER := 0;
    NUM NUMBER := #
BEGIN
    LOOP
        HAP := HAP + NUM;
        NUM := NUM -1;
        EXIT WHEN NUM =0;
    END LOOP;
    DBMS_OUTPUT.PUT_LINE(HAP);
END;
/


예시 📖]

❗스크립트 활성화
SET SERVEROUTPUT ON

✔️스크립트 활성화 확인
SHOW SERVEROUT

💡 방법 1]

ACCEPT S_NUM PROMPT 'START NUMBER?';
ACCEPT N_NUM PROMPT 'START NUMBER?';
<
BEGIN 
    IF &S_NUM > &E_NUM THEN
        DBMS_OUTPUT.PUT_LINE('START MUST BE LESS THAN END');
    ELSE
        FOR K IN &S_NUM .. &E_NUM LOOP 
            DBMS_OUTPUT.PUT_LINE('K=' || K);
        END LOOP;
END IF;
END;
/

💡 방법 2]

ACCEPT S_NUM PROMPT 'START NUMBER?';
ACCEPT E_NUM PROMPT 'START NUMBER?';

DECLARE
    HAP NUMBER := 0;

BEGIN 
    IF &S_NUM > &E_NUM THEN
        DBMS_OUTPUT.PUT_LINE('START MUST BE LESS THAN END');
    ELSE
        FOR K IN &S_NUM .. &E_NUM LOOP
            IF MOD(K,2) = 0 THEN
                HAP := HAP + K;
            END IF;

        END LOOP;
            DBMS_OUTPUT.PUT_LINE('ACCUMULATION OF FROM START TO END;' || HAP);

    END IF;
END;
/

📖 응용 예제 1. 아래의 형식처럼 출력하는 PL/SQL문

/*
1   0   0   0   
0   1   0   0   
0   0   1   0   
0   0   0   1
*/
BEGIN 
    FOR I IN 1 .. 4 LOOP
        FOR K IN 1 .. 4 LOOP
            IF I = K THEN
                DBMS_OUTPUT.PUT('1   ');
            ELSE
                DBMS_OUTPUT.PUT('0   ');
            END IF;
        END LOOP;
        DBMS_OUTPUT.NEW_LINE;
    END LOOP;
END;
/

📖 응용 예제 2. 아래의 형식처럼 출력하는 PL/SQL의 WHILE문

/*
1   0   0   0   
0   1   0   0   
0   0   1   0   
0   0   0   1
*/
DECLARE
    I NUMBER := 1;
    K NUMBER;
BEGIN 
    WHILE I <= 4 LOOP
        K := 1;
        WHILE K <= 4 LOOP
            IF I = K THEN
                DBMS_OUTPUT.PUT('1   ');
            ELSE
                DBMS_OUTPUT.PUT('0   ');
            END IF;
            K := K+1;
        END LOOP;
        I := I+1;
    DBMS_OUTPUT.NEW_LINE;
    END LOOP;
END;
/

📖 응용 예제 3. 1부터 10까지 누적합 구하는 PL/SQL WHILE문

DECLARE
    HAP NUMBER := 0;
    K NUMBER := 1;
BEGIN
    WHILE k <=10 LOOP
        HAP := HAP + K;
        K := K+1;
    END LOOP;
    DBMS_OUTPUT.PUT_LINE('Accumulation from 1 to 10:'||HAP);
   
END;
/

📙 문제 1.구구단 형식처럼 출력하는 PL/SQL문

BEGIN 
    FOR I IN 1 .. 9 LOOP
        FOR K IN 2 .. 9 LOOP
                DBMS_OUTPUT.PUT(K ||'*'||I||'='||K*I||'   ');
       END LOOP;
            DBMS_OUTPUT.NEW_LINE;
    END LOOP;
END;
/

📙 문제 2.구구단 형식처럼 출력하는 PL/SQL문의 WHILE문

DECLARE
    I NUMBER := 1;
    K NUMBER;
BEGIN
    WHILE I <= 9 LOOP
    K :=2 ;
    WHILE K <= 9 LOOP
        DBMS_OUTPUT.PUT(K ||'*'||I||'='||K*I||'   ');
        K := K+1;
    END LOOP;
    I := I+1;
    DBMS_OUTPUT.NEW_LINE;
    END LOOP;
END;
/

📙 문제 3]

ACCEPT SNUM PROMPT 'INPUT START NUMBER?';
ACCEPT ENUM PROMPT 'INPUT END NUMBER?';

DECLARE
    HAP NUMBER;
    SNUM NUMBER := &SNUM;
    ENUM NUMBER := &ENUM;
BEGIN
    /*
      --문] 시작값부터 종료값까지의 누적합.
      --    단,시작값이 종료값보다 큰 경우 '시작값이 종료값보다 커요'라는
      --    메시지를 출력하여 프로그램을 끝내는 코드도 추가하여라
	  -- LOOP문 사용(FOR문 혹은 WHILE문 말고) 
    */
    IF &SNUM > &ENUM THEN
        DBMS_OUTPUT.PUT('END NUMBER IS LESS THAN START NUMBER');
    ELSE
        HAP := 0;
        LOOP 
            HAP := HAP + SNUM;
            SNUM := SNUM +1;
            EXIT WHEN &ENUM < SNUM;
        END LOOP;
        END IF; 
        DBMS_OUTPUT.PUT_LINE('ACCUMULATION FROM ' || &SNUM || ' TO ' || &ENUM || ' IS ' || HAP);
END;
/

2. EXIT문

EXIT WHEN condition;

조건식 ⭐]

사용 예
SQL>SET SERVEROUTPUT ON
SQL>DECLARE
2 v_init NUMBER:=1;
3 v_end NUMBER := 10;
4 BEGIN
5 WHILE v_init <=v_end LOOP
6 DBMS_OUTPUT.PUT_LINE(v_init);
7 v_init:=v_init+1;
8 END LOOP;
9 END;
/ -------------->반드시

[EXIT문 테스트 예시 1 📖]

ACCEPT NUM PROMPT 'INPUT NUMBER?'

DECLARE
    NUM NUMBER := &NUM;
BEGIN
    WHILE 1 = 1 LOOP
        DBMS_OUTPUT.PUT_LINE('NUM IS'||NUM);
        NUM := NUM -1;
        --DBMS_OUTPUT.PUT_LINE('INFINITE lOOP');
        EXIT WHEN MOD(NUM,5) = 1;
    END LOOP;
END;
/

[EXIT문 테스트 예시 2 📖]

ACCEPT title PROMPT 'INPUT TITLE?'
ACCEPT username PROMPT 'INPUT username?'

DECLARE
    ID BBS.username%type:='&USERNAME';
    TITLE BBS.title%type:='&TITLE';
BEGIN
    INSERT INTO BBS VALUES(SEQ_BBS.NEXTVAL,TITLE,ID,SYSDATE);

    IF SQL%FOUND THEN
        DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT||'ROWS INSERTED');
        COMMIT;
    END IF;
    EXDEPTION
    WHEN OTHERS THEN 
        ROLLBACK;
        DBMS_OUTPUT.PUT_LINE('ERROR:'||SQLRRM);
 END;
 /

3.예외 처리

🔖 중요 ]
- EXCEPTION : PL/SQL에서 발생하는 ERROR
- PL/SQL블랑 었었부에선 발생한 예외는 처리하지 못한다
- 실행부에서 발생한 예외만 처리 할 수 있다
- ORACLE Server 에러가 발생하면 이와 관련된 EXCEPTION이 자동 발생

[10년후 나이 입력 예시 📖]

➖ 실행부 및 예외처리 선언부 작성
ACCEPT AGE PROMPT '나이 입력?'
 
DECLARE
   -- AGE- NUMBER;
    AGE_ VARCHAR2(20);
    MY_NOT_NUMBER EXCEPTION;--예외선언
    --PRAGMA EXCEPTION_INIT(MY_NOT_NUMBER,-06550);
    PRAGMA EXCEPTION_INIT(MY_NOT_NUMBER,-06502);
   
BEGIN
    --실행부
    AGE_ := '&AGE';

    DBMS_OUTPUT.PUT_LINE('10년 후 나이는 ' || (AGE_ +10));

    --예외 처리부
    EXCEPTION
    WHEN MY_NOT_NUMBER THEN
        DBMS_OUTPUT.PUT_LINE('나이는 숫자만...');
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('관리자에게 문의:010-1234-5678');
END;
/

[짝수만 입력하는 예외선언 예시 📖]

ACCEPT NUM PROMPT '숫자 입력?'
DECLARE
    EVEN_NOT_NUMBER EXCEPTION;
BEGIN
    IF MOD(&NUM, 2)=0 THEN
        RAISE EVEN_NOT_NUMBER;
    END IF;

    DBMS_OUTPUT.PUT_LINE(&NUM || '는 홀수');
    EXCEPTION
    WHEN EVEN_NOT_NUMBER THEN
        DBMS_OUTPUT.PUT_LINE('짝수는 입력 불가용');
END;
/

[예외처리 테스트 예시 1 📖]

ACCEPT USERNAME PROMPT '아이디 입력?'

DECLARE
    USERNAME_ BBS.username%type := 'USERNAME';
    TITLE_ BBS.title%type;

BEGIN
    SELECT USERNAME, TITLE INTO USERNAME_, TITLE_ FROM BBS WHERE NO=6;
    DBMS_OUTPUT.PUT_LINE(USERNAME_);
    DBMS_OUTPUT.PUT_LINE(TITLE_);
END;
/

💡조회하는 경우, SELECT USERNAME, TITLE FROM BBS WHERE NO=6;

[예외처리 테스트 예시 2 📖]

ACCEPT NO PROMPT '글 번호 입력?'

DECLARE
    NO_ BBS.username%type := &NO;
    TITLE_ BBS.title%type;
    USERNAME_ BBS.username%type;
    VAL NUMBER;

BEGIN
    --SELECT NO, USERNAME, TITLE INTO NO_, USERNAME_, TITLE_ FROM BBS;
    SELECT NO, USERNAME, TITLE INTO NO_, USERNAME_, TITLE_ FROM BBS WHERE NO=NO_;
    DBMS_OUTPUT.PUT_LINE('글번호:' || NO_ || ',아이디:' || USERNAME_ || ',제목:' || TITLE_);

    VAL := 10/0;

    --예외처리부
    EXCEPTION 
    WHEN TOO_MANY_ROWS THEN
        DBMS_OUTPUT.PUT_LINE('다중행이 출력되면 안되요');
    WHEN NO_DATA_FOUND THEN
        DBMS_OUTPUT.PUT_LINE('레코드가 없어요');
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('예외가 발생했어요');
        DBMS_OUTPUT.PUT_LINE('에러코드:' || SQLCODE);
        DBMS_OUTPUT.PUT_LINE('에러메시지:' || SQLERRM);
END;
/

0개의 댓글