더북(TheBook)

커서와 FOR문

9장에서 FOR문의 기본 형태와 사용법에 대해 배웠는데, FOR문은 커서와 함께 또 다른 형태로 사용할 수 있다. 복습하는 차원에서 FOR문을 살펴 보자.

기본 FOR문 구문 형식

    FOR 인덱스 IN [REVERSE]초깃값..최종값
    LOOP
      처리문;
    END LOOP;

커서와 함께 FOR문을 사용할 때는, “초깃값..최종값” 대신 커서가 위치한다.

커서와 함께 사용될 경우 FOR문 구문 형식

    FOR 레코드 IN 커서명(매개변수1, 매개변수2, ...)
    LOOP
      처리문;
    END LOOP;

FOR문의 루프 조건인 초깃값과 최종값 대신 커서명이, 인덱스 대신 레코드가 위치한다. 그리고 해당 커서의 패치가 끝나면 자동으로 루프가 종료된다. 다음 절에서 상세히 설명할 텐데, 레코드는 테이블 로우 전체를 담아둘 수 있는 오라클 데이터 타입 중의 하나라는 것만 알아 두자. 그럼 위 익명 블록을 FOR문으로 바꾸어 보자.

입력

    DECLARE
      -- 커서 선언, 매개변수로 부서코드를 받는다.
      CURSOR cur_emp_dep ( cp_department_id employees.department_id%TYPE )
      IS
      SELECT emp_name
        FROM employees
       WHERE department_id = cp_department_id;

    BEGIN
      -- FOR문을 통한 커서 패치작업
      FOR emp_rec IN cur_emp_dep(90)
      LOOP
        -- 사원명을 출력, 레코드 타입은 레코드명.컬럼명 형태로 사용
        DBMS_OUTPUT.PUT_LINE(emp_rec.emp_name);
      END LOOP;

    END;

결과

    Steven King
    Neena Kochhar
    Lex De Haan

결과를 보면 알 수 있듯이 커서와 FOR문을 같이 사용할 때는 커서를 열고 패치하고 닫을 필요가 전혀 없다. 코드가 훨씬 줄어들어 깔끔해졌고 원하던 결과도 제대로 출력되었다. 아예 커서 선언 부분을 없애고 FOR문에 직접 커서 정의 내용을 넣을 수도 있다.

입력

    DECLARE

    BEGIN
      -- FOR문을 통한 커서 패치 작업(커서를 선언할 때 정의 부분을 FOR문에 직접 기술)
      FOR emp_rec IN ( SELECT emp_name
                         FROM employees
                        WHERE department_id = 90
                    )
      LOOP
        -- 사원명을 출력, 레코드 타입은 레코드명.컬럼명 형태로 사용
        DBMS_OUTPUT.PUT_LINE(emp_rec.emp_name);
      END LOOP;

    END;

결과

    Steven King
    Neena Kochhar
    Lex De Haan

커서를 정의하는 SELECT문을 직접 FOR문 안으로 옮기더라도 동일한 결과가 나옴을 확인할 수 있다. 어떤 형태의 FOR문을 사용할 것인지는 개인의 선택이지만 코드의 가독성과 재사용 측면에서 보면 이 방법보다는 커서를 직접 선언해서 사용하는 것이 좋다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.