PL/SQL

PL/SQL 기초 03강 — 제어문: IF·CASE·LOOP

🎯 학습 목표

  • IF/ELSIF/ELSE로 조건 분기를 작성한다.
  • CASE 문(실행)과 CASE 식(값 반환)을 구분한다.
  • LOOP, WHILE LOOP, FOR LOOP로 반복을 작성하고 EXIT WHEN·CONTINUE로 흐름을 제어한다.

📖 IF / ELSIF / ELSE

DECLARE
  v_score NUMBER := 75;
  v_grade VARCHAR2(10);
BEGIN
  IF v_score >= 90 THEN
    v_grade := '수';
  ELSIF v_score >= 80 THEN
    v_grade := '우';
  ELSIF v_score >= 70 THEN
    v_grade := '미';
  ELSE
    v_grade := '가';
  END IF;
  DBMS_OUTPUT.PUT_LINE('점수 ' || v_score || ' → 등급: ' || v_grade);
END;
/
  • 조건 비교에는 =, <>(또는 !=), <, >, <=, >=를 씁니다.
  • ELSIF는 한 단어입니다(ElseIf 아님). 개수 제한 없이 이어 쓸 수 있습니다.
  • NULL 비교는 IS NULL / IS NOT NULL을 씁니다(= NULL은 항상 FALSE).

📖 CASE 문과 CASE 식

DECLARE
  v_dept NUMBER := 20;
  v_name VARCHAR2(20);
  v_bonus NUMBER;
BEGIN
  -- CASE 문: 조건에 따라 실행할 문장을 선택
  CASE v_dept
    WHEN 10 THEN v_name := '회계';
    WHEN 20 THEN v_name := '연구';
    WHEN 30 THEN v_name := '영업';
    ELSE         v_name := '기타';
  END CASE;

  -- CASE 식: 값을 반환하는 표현식 (대입이나 SQL 안에 삽입 가능)
  v_bonus := CASE
               WHEN v_dept = 10 THEN 500
               WHEN v_dept = 20 THEN 300
               ELSE 100
             END;
  DBMS_OUTPUT.PUT_LINE(v_name || ' 부서 보너스: ' || v_bonus);
END;
/

CASE 문에서 ELSE가 없는데 어떤 WHEN도 맞지 않으면 CASE_NOT_FOUND 예외가 발생합니다. 항상 ELSE를 두거나 가능한 값을 모두 처리하세요.

💻 LOOP + EXIT WHEN / CONTINUE

-- 기본 LOOP: EXIT WHEN으로 탈출
DECLARE
  v_i NUMBER := 1;
BEGIN
  LOOP
    DBMS_OUTPUT.PUT_LINE('반복: ' || v_i);
    v_i := v_i + 1;
    EXIT WHEN v_i > 5;   -- 조건이 참이면 루프 탈출
  END LOOP;
END;
/

-- CONTINUE: 현재 반복을 건너뛰고 다음 반복으로
BEGIN
  FOR i IN 1..10 LOOP
    CONTINUE WHEN MOD(i, 2) = 0;    -- 짝수는 건너뜀
    DBMS_OUTPUT.PUT_LINE('홀수: ' || i);
  END LOOP;
END;
/

EXIT WHEN 조건을 빠뜨리면 무한 루프가 됩니다. 반드시 탈출 조건을 명시하세요.

💻 WHILE LOOP와 FOR LOOP

-- WHILE: 진입 전에 조건 검사
DECLARE
  v_n   NUMBER := 1;
  v_sum NUMBER := 0;
BEGIN
  WHILE v_n <= 10 LOOP
    v_sum := v_sum + v_n;
    v_n   := v_n + 1;
  END LOOP;
  DBMS_OUTPUT.PUT_LINE('1~10 합계: ' || v_sum);  -- 55
END;
/

-- FOR: 범위를 지정하면 카운터 변수를 자동 선언·증가
BEGIN
  FOR i IN 1..5 LOOP
    DBMS_OUTPUT.PUT_LINE('i = ' || i);
  END LOOP;
  -- 역방향: FOR i IN REVERSE 1..5 LOOP
END;
/

⚠️ 주의사항

  • FOR LOOP의 루프 변수(i)는 루프 안에서만 유효합니다. DECLARE 구역에 따로 선언하지 않으며, 루프 안에서 값을 변경하려 하면 컴파일 오류가 납니다.
  • IF·CASE 문은 반드시 END IF; / END CASE;로 닫아야 합니다. 빠뜨리면 컴파일 오류입니다.
  • 복잡한 중첩 루프에서 특정 루프를 탈출하려면 레이블(<<outer>>)과 EXIT outer를 조합합니다.

💡 팁

  • FOR LOOP는 반복 횟수가 정해진 경우에 가장 간결합니다. 커서와 함께 쓰는 FOR 루프(커서 FOR 루프)는 5강에서 배웁니다.
  • WHILE LOOP는 반복 횟수를 미리 알 수 없을 때 씁니다. 기본 LOOP는 루프 중간에 조건을 확인해야 할 때 쓰는 경우가 많습니다.