더북(TheBook)

4단계: 커서 닫기

패치 작업이 끝나고 반복문을 빠져 나오면 커서 사용이 모두 끝났으므로 다음과 같이 반드시 커서를 닫아야 한다.

    CLOSE 커서명;

그럼 실제로 명시적 커서를 사용해 보자. 90번 부서에 속한 사원의 이름(총 3명)을 출력하는 익명 블록을 만들어 보자.

입력

    DECLARE
      -- 사원명을 받아오기 위한 변수 선언
      vs_emp_name employees.emp_name%TYPE;

      -- 커서 선언, 매개변수로 부서코드를 받는다.
      CURSOR cur_emp_dep ( cp_department_id employees.department_id%TYPE )
      IS
      SELECT emp_name
        FROM employees
       WHERE department_id = cp_department_id;
    BEGIN
      -- 커서 오픈 (매개변수로 90번 부서를 전달)
      OPEN cur_emp_dep (90);

      -- 반복문을 통한 커서 패치작업
      LOOP
        -- 커서 결과로 나온 로우를 패치함 (사원명을 변수에 할당)
        FETCH cur_emp_dep INTO vs_emp_name;

        -- 패치된 참조 로우가 더 없으면 LOOP 탈출
        EXIT WHEN cur_emp_dep%NOTFOUND;

        -- 사원명을 출력
        DBMS_OUTPUT.PUT_LINE(vs_emp_name);

      END LOOP;

      -- 반복문 종료 후 커서 닫기
      CLOSE cur_emp_dep;
    END;

결과

    Steven King
    Neena Kochhar
    Lex De Haan

커서와 LOOP문을 사용한 익명 블록인데 몇 가지 주의할 점을 짚어 보자. 커서를 사용할 때는 반드시 먼저 커서를 열고 사용이 끝나면 닫아야 한다(‘닫는다’는 것은 메모리상에 존재하는 커서의 쿼리 결과를 소멸시킴을 의미). 간혹 커서를 닫는 것을 잊는 개발자들이 있는데, 사실 해당 프로시저가 종료되면 오라클은 커서를 자동으로 닫아 준다. 하지만 오라클이 PL/SQL 블록이나 서브 프로그램을 실행하면서 닫히지 않은 커서를 닫는 작업 역시 오버헤드를 발생시키므로 커서는 항상 명시적으로 닫도록 하자.

두 번째로, LOOP문 내부를 살펴 보자. 맨 처음 패치를 해서 사원명을 vs_emp_name라는 변수에 할당했고, 뒤이어 반환된 로우가 없으면 루프를 빠져 나가게 작성했다. 이때, ‘%NOTFOUND’ 속성을 사용했는데, 이 속성은 패치된 로우가 없을 때는 TRUE를 반환한다는 점을 명심하자. 따라서 EXIT 구문과 사원명을 출력하는 부분의 순서를 바꾸면 마지막 사원명이 한번 더 출력된다.

입력

    ...
    -- 세 번째 사원을 출력한 뒤 빠져 나가지 않고, 루프를 네 번째 돌 때 패치된 로우가 없어 마지막 사원명이 한번 더 출력됨
    DBMS_OUTPUT.PUT_LINE(vs_emp_name);
    EXIT WHEN cur_emp_dep%NOTFOUND;
    ...

결과

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