③ 커서 변수에서 결과 집합 가져오기
커서를 구성하는 쿼리에 커서 변수까지 연결했으니 커서 변수에서 결과 집합을 가져오는 패치 작업이 남았는데, 이 때도 FETCH 문을 사용한다.
• FETCH 커서 변수명 INTO 변수1, 변수2, ...; 혹은 • FETCH 커서 변수명 INTO 레코드명;
해당 커서에 정의한 결과 집합 개수에 따라 변수에 받아올 수도, 레코드를 정의해서 받아올 수도 있다. 또한 커서 변수를 사용할 때는 커서를 닫는 작업이 필요 없다. 그럼 90번 부서에 속한 사원명을 출력하는 예제를 커서 변수로 구현해 보자.
입력
DECLARE
-- 사원명을 받아오기 위한 변수 선언
vs_emp_name employees.emp_name%TYPE;
-- 약한 커서 타입 선언
TYPE emp_dep_curtype IS REF CURSOR;
-- 커서 변수 선언
emp_dep_curvar emp_dep_curtype;
BEGIN
-- 커서 변수를 사용한 커서 정의 및 오픈
OPEN emp_dep_curvar FOR SELECT emp_name
FROM employees
WHERE department_id = 90;
-- LOOP문
LOOP
-- 커서 변수를 사용해 결과 집합을 vs_emp_name 변수에 할당
FETCH emp_dep_curvar INTO vs_emp_name;
-- 더 이상 패치된 참조 로우가 없으면 LOOP 탈출(커서 변수를 이용한 커서 속성 참조)
EXIT WHEN emp_dep_curvar%NOTFOUND;
-- 사원명을 출력
DBMS_OUTPUT.PUT_LINE(vs_emp_name);
END LOOP;
END;
결과
Steven King
Neena Kochhar
Lex De Haan
이번에는 빌트인 커서 타입인 SYS_REFCURSOR를 사용해 보자.
입력
DECLARE
-- 사원명을 받아오기 위한 변수 선언
vs_emp_name employees.emp_name%TYPE;
-- SYS_REFCURSOR 타입의 커서 변수 선언
emp_dep_curvar SYS_REFCURSOR;
BEGIN
-- 커서 변수를 사용한 커서 정의 및 오픈
OPEN emp_dep_curvar FOR SELECT emp_name
FROM employees
WHERE department_id = 90;
-- LOOP문
LOOP
-- 커서 변수를 사용해 결과 집합을 vs_emp_name 변수에 할당
FETCH emp_dep_curvar INTO vs_emp_name;
-- 더 이상 패치된 참조 로우가 없으면 LOOP 탈출(커서 변수를 이용한 커서 속성 참조)
EXIT WHEN emp_dep_curvar%NOTFOUND;
-- 사원명을 출력
DBMS_OUTPUT.PUT_LINE(vs_emp_name);
END LOOP;
END;
결과
Steven King
Neena Kochhar
Lex De Haan
SYS_REFCURSOR를 사용하면 별도로 커서 타입을 선언하지 않고도 같은 결과를 얻을 수 있다. 커서 변수에 대해 정리해 보면, 강한 커서 타입이 아닌 약한 커서 타입을 사용할 때는 SYS_REFCURSOR 타입을, 강한 커서 타입을 사용해야 한다면 REF CURSOR를 사용하는 것이 여러 모로 편리하다.