DBMS

오라클 커서(CURSOR)

IT 기록하는 사람 2023. 11. 30. 11:30

커서?
커서란 특정 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;

문제점

커서 사용에는 몇 가지 주의해야 할 문제점이 있을 수 있습니다.

  1. 성능 문제:
    • 커서를 잘못 사용하면 성능에 영향을 줄 수 있습니다. 특히 루프를 통해 하나씩 데이터를 가져오는 방식은 처리 시간을 증가시킬 수 있습니다.
    • 대량의 데이터를 처리할 때는 커서를 사용하는 대신 집합 기반의 연산을 고려해야 합니다.
  2. 커서를 올바르게 닫지 않을 경우:
    • 명시적 커서를 사용할 때 커서를 열고 사용한 뒤에는 항상 닫아야 합니다. 닫지 않을 경우 메모리 누수가 발생할 수 있습니다.
    • 예외 처리를 통해 커서를 닫는 로직을 구현하는 것이 좋습니다.
  3. 커서 사용 시 롤백과 커밋 관리:
    • 커서를 열고 데이터를 변경한 후 롤백하거나 커밋해야 하는데, 커서를 올바르게 다루지 않으면 데이터 일관성 문제가 발생할 수 있습니다.
  4. 너무 많은 커서 사용:
    • 하나의 프로시저나 프로그램에서 너무 많은 커서를 사용하면 메모리 소비와 리소스 사용량이 증가할 수 있습니다.
  5. 코드 가독성과 유지보수성 저하:
    • 커서를 적절하게 사용하지 않으면 코드가 복잡해지고 가독성이 떨어질 수 있으며, 유지보수가 어려워질 수 있습니다.

이러한 문제점들을 해결하기 위해서는 커서를 사용할 때 최적화된 방법을 선택하고, 데이터베이스 설계 및 쿼리 최적화를 고려하여 성능을 향상시키는 것이 중요합니다. 또한 커서를 사용할 때 메모리 누수를 방지하고, 커서를 안전하게 닫고 예외를 처리하는 것이 좋습니다.