커서?
커서란 특정 SQL 문장을 처리한 결과를 담고 있는 영역을 가리키는 일종의 포인터입니다. 커서를 사용하면 처리된 SQL 문장의 결과 집합에 접근할 수 있습니다.
커서의 종류
명시적(Explicit) 커서: 사용자가 선언해서 생성 후 사용하는 SQL 커서, 주로 여러 개의 행을 처리하고자 할 경우 사용.
묵시적(Implicit) 커서: 오라클에서 자동으로 선언해주는 SQL 커서, 사용자는 생성 유무를 알 수 없다.
커서의 속성
커서를 open하고 나서 fetch가 발생하면 true값을 반환
%FOUND : 할당할 레코드가 있는 경우 true 값을 반환
%isOpen : 커서가 오픈 상태일 경우 true 값을 반환
%NotFound : 할당할 레코드가 없는 경우 true 값을 반환
%RowCount : 카운터 역할을 한다. 커서가 오픈됐을 경우 0, 패치가 발생할 때마다 1씩 증가한다.
커서의 처리단계(명시적 커서)
DECLARE
emp_id number(4);
emp_name varchar2(10);
emp_salary number(10);
-- 명시적 커서 선언 (Cursor [커서이름])
CURSOR cul is
SELECT empno, ename, sal
FROM emptest1
WHERE deptno = 30;
BEGIN
-- 명시적 커서 오픈 (Open [커서이름])
OPEN CRL;
dbms_output.put_line('사번 이름 급여');
LOOP
-- 커서에서 데이터 추출 (Fetch [커서이름])
FETCH cul INTO emp_id, emp_name, emp_salary;
EXIT WHEN cul%NotFound;
dbms_output.put_line(emp_id||' '||emp_name||' '||emp_salary);
END LOOP;
--커서 종료 (Close [커서이름])
CLOSE cul;
END;
묵시적 커서 사용
속성 사용 시 SQL%NotFound, SQL%RowCount, SQL%Found, SQL%isOpen과 같이 SQL을 넣어 사용한다.
DECLARE
cnt1 number;
cnt2 number;
BEGIM
SELECT count(*) INTO cnt1
FROM emp
WHERE deptno = 30;
cnt2 := sql%rowcount;
dbms_output.put_line('cnt1의 값 : ' || cnt1);
dbms_output.put_line('cnt2의 값 : ' || cnt2);
end;
문제점
커서 사용에는 몇 가지 주의해야 할 문제점이 있을 수 있습니다.
- 성능 문제:
- 커서를 잘못 사용하면 성능에 영향을 줄 수 있습니다. 특히 루프를 통해 하나씩 데이터를 가져오는 방식은 처리 시간을 증가시킬 수 있습니다.
- 대량의 데이터를 처리할 때는 커서를 사용하는 대신 집합 기반의 연산을 고려해야 합니다.
- 커서를 올바르게 닫지 않을 경우:
- 명시적 커서를 사용할 때 커서를 열고 사용한 뒤에는 항상 닫아야 합니다. 닫지 않을 경우 메모리 누수가 발생할 수 있습니다.
- 예외 처리를 통해 커서를 닫는 로직을 구현하는 것이 좋습니다.
- 커서 사용 시 롤백과 커밋 관리:
- 커서를 열고 데이터를 변경한 후 롤백하거나 커밋해야 하는데, 커서를 올바르게 다루지 않으면 데이터 일관성 문제가 발생할 수 있습니다.
- 너무 많은 커서 사용:
- 하나의 프로시저나 프로그램에서 너무 많은 커서를 사용하면 메모리 소비와 리소스 사용량이 증가할 수 있습니다.
- 코드 가독성과 유지보수성 저하:
- 커서를 적절하게 사용하지 않으면 코드가 복잡해지고 가독성이 떨어질 수 있으며, 유지보수가 어려워질 수 있습니다.
이러한 문제점들을 해결하기 위해서는 커서를 사용할 때 최적화된 방법을 선택하고, 데이터베이스 설계 및 쿼리 최적화를 고려하여 성능을 향상시키는 것이 중요합니다. 또한 커서를 사용할 때 메모리 누수를 방지하고, 커서를 안전하게 닫고 예외를 처리하는 것이 좋습니다.
'DBMS' 카테고리의 다른 글
GRA_*.log 파일 이해 (0) | 2023.10.31 |
---|---|
오라클 PLS-00302 구성 요소가 정의되어야 합니다. (0) | 2023.10.27 |
Lock wait timeout exceeded; try restarting transaction (0) | 2023.10.11 |
오라클 시퀀스 (0) | 2023.10.10 |