오라클에서 사용할 수 있는 커서 변수는 기본적으로 SYS_REFCURSOR 를 제공하고 있습니다. 대부분의 경우 SYS_REFCURSOR를 사용하거나, 필요에 따라 사용자가 커서 타입을 정의하여 사용할 수 있어요.
커서와 관련된 몇 가지 추가 정보와 기법이 있으니 참고해 보세요.
정적 커서 (Static Cursor)
- PL/SQL 내에서 일반적으로 사용하는 커서로, 특정 쿼리를 미리 정의하고 그 쿼리만을 실행합니다.
- 정적 커서는
CURSOR키워드를 통해 미리 정의된 쿼리를 기반으로 실행됩니다. - 정적 커서는 커서를 미리 정의하고 오픈 할 때는 고정된 쿼리를 사용하므로, 동적 SQL 구문처럼 유연하지는 않아요.
예시 (이렇게 사용하는 경우는 거의 없고 파라미터가 있는 커서를 설정합니다, 관련 자료는 다른 게시물에 적어두었어요.)
DECLARE
CURSOR emp_cursor IS
SELECT empno, ename FROM emp;
v_empno emp.empno%TYPE;
v_ename emp.ename%TYPE;
BEGIN
OPEN emp_cursor;
LOOP
FETCH emp_cursor INTO v_empno, v_ename;
EXIT WHEN emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('EmpNo: ' || v_empno || ', Name: ' || v_ename);
END LOOP;
CLOSE emp_cursor;
END;
/
EmpNo: 7698, Name: BLAKE
EmpNo: 7782, Name: CLARK
EmpNo: 7566, Name: JONES
EmpNo: 7788, Name: SCOTT
EmpNo: 7902, Name: FORD
EmpNo: 7369, Name: SMITH
EmpNo: 7499, Name: ALLEN
EmpNo: 7521, Name: WARD
EmpNo: 7654, Name: MARTIN
EmpNo: 7844, Name: TURNER
EmpNo: 7876, Name: ADAMS
EmpNo: 7900, Name: JAMES
EmpNo: 7934, Name: MILLER
EmpNo: 7839, Name: KING
PL/SQL procedure successfully completed.
동적 커서와 SYS_REFCURSOR
SYS_REFCURSOR는 동적 커서(dynamic cursor)로서, 런타임에 다양한 쿼리를 실행하고자 할 때 유용합니다.- 여러 가지 SQL 문장을 실행할 수 있는 유연성을 제공하므로,
REF CURSOR의 대안으로 사용할 수 있어요.
예시
DECLARE
v_cursor SYS_REFCURSOR;
v_empno emp.empno%TYPE;
v_ename emp.ename%TYPE;
BEGIN
OPEN v_cursor FOR 'SELECT empno, ename FROM emp WHERE deptno = :dept_no' USING 10;
LOOP
FETCH v_cursor INTO v_empno, v_ename;
EXIT WHEN v_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('EmpNo: ' || v_empno || ', Name: ' || v_ename);
END LOOP;
CLOSE v_cursor;
END;
/
EmpNo: 7782, Name: CLARK
EmpNo: 7934, Name: MILLER
EmpNo: 7839, Name: KING
PL/SQL procedure successfully completed.
사용자 정의 REF CURSOR 타입
SYS_REFCURSOR외에도 커서가 가져올 데이터 형식이 고정되어 있다면REF CURSOR타입을 사용자 정의해서 사용할 수 있습니다.- 예를 들어,
TYPE my_cursor IS REF CURSOR RETURN emp%ROWTYPE;과 같이 특정 테이블이나 레코드 형식을 반환하는 커서를 정의하는 방식입니다.
현재 오라클에서 기본적으로 제공하는 프리디파인드 커서로는 SYS_REFCURSOR가 대표적이며, 이를 통해 대부분의 동적 커서 작업이 해결 가능합니다.
예시
DECLARE
TYPE emp_cursor_type IS REF CURSOR RETURN emp%ROWTYPE;
v_emp_cursor emp_cursor_type;
v_emp_record emp%ROWTYPE;
BEGIN
OPEN v_emp_cursor FOR SELECT * FROM emp WHERE job = 'MANAGER';
LOOP
FETCH v_emp_cursor INTO v_emp_record;
EXIT WHEN v_emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('EmpNo: ' || v_emp_record.empno ||
', Name: ' || v_emp_record.ename ||
', Job: ' || v_emp_record.job);
END LOOP;
CLOSE v_emp_cursor;
END;
/
EmpNo: 7698, Name: BLAKE, Job: MANAGER
EmpNo: 7782, Name: CLARK, Job: MANAGER
EmpNo: 7566, Name: JONES, Job: MANAGER
PL/SQL procedure successfully completed.
커서 변수 없이 커서 제어하기
- 커서 타입을 정의하지 않고도 커서와 비슷한 방식으로 데이터를 처리할 수 있는 몇 가지 기법이 있습니다.
FOR루프와 함께 사용하는 인라인 커서- 위와 같은 인라인 커서는
FOR루프 내에서 한 번에 하나의 레코드를 가져오므로, 따로 커서 변수를 선언하지 않고도 반복 작업을 수행할 수 있어요.
예시
BEGIN
FOR rec IN (SELECT empno, ename FROM emp)
LOOP
DBMS_OUTPUT.PUT_LINE (rec.empno || ' ' || rec.ename);
END LOOP;
END;
/
7698 BLAKE
7782 CLARK
7566 JONES
7788 SCOTT
7902 FORD
7369 SMITH
7499 ALLEN
7521 WARD
7654 MARTIN
7844 TURNER
7876 ADAMS
7900 JAMES
7934 MILLER
7839 KING
PL/SQL procedure successfully completed.
