오라클 데이터베이스에서 커서(Cursor)는 SQL 문 실행 결과를 메모리에서 저장하는 일종의 컨테이너입니다. 커서를 사용하면 여러 행을 포함하는 쿼리 결과를 순차적으로 처리할 수 있습니다. 특히, PL/SQL 블록에서 프로그래밍적으로 데이터를 조작할 때 유용합니다.
이 글에서는 커서의 기본 개념부터 사용법, 예제, 그리고 실무 활용까지 다양한 내용을 자세히 다룹니다.
1. 커서란?
커서(Cursor)는 SQL 실행 결과를 참조하는 포인터로, PL/SQL 블록에서 SQL 문 실행 결과를 행 단위로 처리할 때 사용됩니다.
1.1. 커서의 종류
오라클에서 커서는 다음과 같이 두 가지로 나뉩니다:
암시적 커서 (Implicit Cursor)
- Oracle Database가 SQL 문을 실행할 때 자동으로 생성됩니다.
- 예:
INSERT
,UPDATE
,DELETE
등 DML 문 실행 시 사용.
명시적 커서 (Explicit Cursor)
- 프로그래머가 직접 선언하고 제어하는 커서입니다.
- 주로 SELECT 문으로 다중 행을 처리할 때 사용됩니다.
2. 암시적 커서
2.1. 개념
- 오라클은 SQL 문 실행 후 결과를 암시적으로 관리합니다.
- 실행 결과는
SQL%
속성을 사용하여 참조할 수 있습니다.
2.2. 주요 속성
암시적 커서의 속성은 다음과 같습니다:
SQL%FOUND
: 마지막 SQL 문이 하나 이상의 행에 영향을 미쳤다면TRUE
.SQL%NOTFOUND
: 마지막 SQL 문이 영향을 미치지 않았다면TRUE
.SQL%ROWCOUNT
: 마지막 SQL 문으로 영향을 받은 행 수.SQL%ISOPEN
: 커서가 열려 있는지 확인 (항상FALSE
, 암시적 커서는 자동으로 닫히기 때문).
2.3. 예제
DECLARE
v_rows NUMBER;
BEGIN
UPDATE employees
SET salary = salary * 1.1
WHERE department_id = 10;
IF SQL%FOUND THEN
v_rows := SQL%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE('총 ' || v_rows || '개 행이 업데이트되었습니다.');
ELSE
DBMS_OUTPUT.PUT_LINE('업데이트된 행이 없습니다.');
END IF;
END;
/
3. 명시적 커서
3.1. 개념
- 명시적 커서는 SELECT 문으로 반환된 다중 행을 제어하기 위해 사용됩니다.
- 프로그래머가 커서를 선언, 열기, 가져오기, 닫기 과정을 명시적으로 처리해야 합니다.
3.2. 주요 단계
명시적 커서를 사용하는 과정은 다음과 같습니다:
커서 선언
- SELECT 문을 기반으로 커서를 정의합니다.
CURSOR cursor_name IS SELECT column1, column2 FROM table_name WHERE condition;
- SELECT 문을 기반으로 커서를 정의합니다.
커서 열기
OPEN
문으로 커서를 실행합니다.OPEN cursor_name;
커서에서 데이터 가져오기
FETCH
문으로 한 행씩 데이터를 가져옵니다.FETCH cursor_name INTO variable1, variable2;
커서 닫기
CLOSE
문으로 커서를 닫습니다.CLOSE cursor_name;
4. 명시적 커서 예제
4.1. 기본 예제
DECLARE
CURSOR emp_cursor IS
SELECT first_name, last_name, salary
FROM employees
WHERE department_id = 10;
v_first_name employees.first_name%TYPE;
v_last_name employees.last_name%TYPE;
v_salary employees.salary%TYPE;
BEGIN
OPEN emp_cursor;
LOOP
FETCH emp_cursor INTO v_first_name, v_last_name, v_salary;
EXIT WHEN emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('이름: ' || v_first_name || ' ' || v_last_name || ', 급여: ' || v_salary);
END LOOP;
CLOSE emp_cursor;
END;
/
4.2. 매개변수가 있는 커서
DECLARE
CURSOR emp_cursor(dept_id NUMBER) IS
SELECT first_name, last_name
FROM employees
WHERE department_id = dept_id;
v_first_name employees.first_name%TYPE;
v_last_name employees.last_name%TYPE;
BEGIN
OPEN emp_cursor(20);
LOOP
FETCH emp_cursor INTO v_first_name, v_last_name;
EXIT WHEN emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('이름: ' || v_first_name || ' ' || v_last_name);
END LOOP;
CLOSE emp_cursor;
END;
/
5. REF CURSOR
REF CURSOR는 명시적 커서의 동적 버전으로, 런타임에 커서 쿼리를 동적으로 정의할 수 있습니다.
5.1. REF CURSOR 선언
DECLARE
TYPE ref_cursor IS REF CURSOR;
v_cursor ref_cursor;
v_first_name employees.first_name%TYPE;
v_last_name employees.last_name%TYPE;
BEGIN
OPEN v_cursor FOR
SELECT first_name, last_name
FROM employees
WHERE department_id = 30;
LOOP
FETCH v_cursor INTO v_first_name, v_last_name;
EXIT WHEN v_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('이름: ' || v_first_name || ' ' || v_last_name);
END LOOP;
CLOSE v_cursor;
END;
/
6. 커서 속성
커서 속성은 커서의 상태를 확인하는 데 사용됩니다.
%FOUND
: 데이터를 가져온 경우TRUE
.%NOTFOUND
: 데이터를 가져오지 못한 경우TRUE
.%ROWCOUNT
: FETCH된 행의 개수.%ISOPEN
: 커서가 열려 있으면TRUE
.
예제
DECLARE
CURSOR emp_cursor IS
SELECT first_name FROM employees WHERE department_id = 10;
v_name employees.first_name%TYPE;
BEGIN
OPEN emp_cursor;
FETCH emp_cursor INTO v_name;
IF emp_cursor%FOUND THEN
DBMS_OUTPUT.PUT_LINE('첫 번째 이름: ' || v_name);
END IF;
CLOSE emp_cursor;
IF NOT emp_cursor%ISOPEN THEN
DBMS_OUTPUT.PUT_LINE('커서가 닫혔습니다.');
END IF;
END;
/
7. 커서 사용 시 주의사항
메모리 관리
- 커서를 열면 메모리를 차지합니다. 사용 후 반드시 닫아야 합니다.
- 닫지 않으면
ORA-01000: maximum open cursors exceeded
오류가 발생할 수 있습니다.
효율적인 사용
- 다중 행 쿼리를 처리할 때만 사용하세요. 단일 행은 암시적 커서로 충분합니다.
- 불필요한 커서 사용은 성능에 부정적인 영향을 미칠 수 있습니다.
중첩 커서
- 커서를 중첩하여 사용하면 코드 복잡도가 증가합니다. 반드시 필요한 경우에만 사용하세요.
8. 결론
오라클 커서는 SQL 쿼리 결과를 다중 행으로 처리해야 할 때 매우 유용한 도구입니다. 암시적 커서는 단순한 DML 작업에 적합하고, 명시적 커서는 복잡한 데이터 처리가 필요한 경우에 적합합니다. 또한, REF CURSOR를 사용하면 동적 쿼리를 처리할 수 있습니다.
커서를 올바르게 사용하면 애플리케이션 성능과 유지보수성을 크게 향상시킬 수 있습니다. 하지만 사용 후 반드시 닫는 등 메모리 관리를 철저히 해야 합니다. 다양한 예제를 통해 커서의 기능을 익히고, 프로젝트에 적절히 활용해 보세요!
'개발 > 오라클' 카테고리의 다른 글
오라클 프로시저의 작성법과 다양한 유형의 예제 (0) | 2025.01.17 |
---|---|
오라클 함수의 작성법과 다양한 유형의 예제 (0) | 2025.01.17 |
데이터베이스 설계: 정규화란 무엇인가? (0) | 2025.01.14 |
다양한 데이터베이스에서 시간대(Time Zone) 처리 (1) | 2025.01.13 |
오라클 쿼리에서 PIVOT 사용하기: 다양한 유형과 실습 (0) | 2025.01.13 |