SQL 커서 사용법: 명시적과 암시적 커서의 차이 및 반복 처리 방법
커서는 SQL에서 결과 집합을 처리하는 데 필요한 객체로, 데이터베이스에서 쿼리 결과를 순차적으로 접근할 수 있게 해줍니다. 명시적 커서는 개발자가 직접 선언하고 제어하는 반면, 암시적 커서는 SQL 문에 의해 자동으로 생성됩니다. 커서를 사용하여 반복적으로 데이터를 처리하는 방법도 배울 수 있습니다.
커서의 개념과 필요성
커서는 SQL에서 쿼리 결과를 처리하기 위한 데이터베이스 객체입니다. SQL 쿼리를 실행하면 결과 집합이 생성되는데, 이 결과 집합을 커서를 통해 순차적으로 접근하고 조작할 수 있습니다. 커서는 데이터베이스에서 여러 행을 처리할 때 유용하며, 특히 반복적으로 데이터를 처리해야 할 경우 필수적인 도구입니다.
커서의 필요성
결과 집합 접근: SQL 쿼리의 결과는 한 번에 모든 데이터를 반환하지만, 커서를 사용하면 결과 집합의 각 행에 대해 개별적으로 작업할 수 있습니다.
복잡한 로직 처리: 비즈니스 로직이나 복잡한 계산을 수행할 때 커서를 이용하면 각 행을 하나씩 처리하면서 필요한 작업을 수행할 수 있습니다.
메모리 관리: 커서는 결과 집합을 메모리에 모두 로드하지 않고, 필요한 만큼만 로드하여 메모리 사용을 효율적으로 관리할 수 있습니다.
예제
다음은 커서를 사용하여 직원 정보를 순차적으로 출력하는 간단한 예제입니다. 이 예제에서는 employees
테이블에서 모든 직원의 이름을 출력합니다.
DECLARE
CURSOR emp_cursor IS
SELECT first_name, last_name FROM employees;
emp_record emp_cursor%ROWTYPE;
BEGIN
OPEN emp_cursor; -- 커서 열기
LOOP
FETCH emp_cursor INTO emp_record; -- 커서에서 행을 가져오기
EXIT WHEN emp_cursor%NOTFOUND; -- 더 이상 행이 없으면 종료
DBMS_OUTPUT.PUT_LINE(emp_record.first_name || ' ' || emp_record.last_name); -- 직원 이름 출력
END LOOP;
CLOSE emp_cursor; -- 커서 닫기
END;
위의 예제에서 emp_cursor
는 employees
테이블에서 직원의 이름을 가져오는 커서입니다. FETCH
문을 사용하여 커서에서 각 행을 가져오고, DBMS_OUTPUT.PUT_LINE
을 통해 직원의 이름을 출력합니다. 커서를 사용함으로써 각 직원의 정보를 하나씩 처리할 수 있게 됩니다.
커서 선언과 사용 방법
커서를 사용하기 위해서는 먼저 커서를 선언하고, 이후에 이를 열고, 데이터를 가져오며, 마지막으로 커서를 닫는 과정이 필요합니다. 이 과정은 PL/SQL 블록 내에서 수행됩니다.
커서 선언
커서를 선언할 때는 CURSOR
키워드를 사용하여 쿼리 문을 정의합니다. 커서를 선언한 후에는 이 커서를 통해 쿼리 결과를 처리할 수 있습니다.
예제: 커서 선언
DECLARE
CURSOR emp_cursor IS
SELECT first_name, last_name FROM employees;
BEGIN
-- 커서 사용 코드가 들어갑니다.
END;
위의 코드에서 emp_cursor
라는 이름의 커서를 선언하고, employees
테이블에서 직원의 이름을 가져오는 쿼리를 정의했습니다.
커서 열기
커서를 열면 결과 집합이 메모리에 로드됩니다. 커서를 열기 위해서는 OPEN
문을 사용합니다.
예제: 커서 열기
OPEN emp_cursor; -- 커서 열기
데이터 가져오기
커서에서 데이터를 가져오기 위해서는 FETCH
문을 사용합니다. FETCH
문은 커서에서 다음 행을 가져오며, 가져온 데이터를 변수에 저장합니다.
예제: 데이터 가져오기
DECLARE
emp_record emp_cursor%ROWTYPE; -- 커서의 행 타입을 가진 변수 선언
BEGIN
OPEN emp_cursor; -- 커서 열기
FETCH emp_cursor INTO emp_record; -- 커서에서 행을 가져오기
DBMS_OUTPUT.PUT_LINE(emp_record.first_name || ' ' || emp_record.last_name); -- 직원 이름 출력
CLOSE emp_cursor; -- 커서 닫기
END;
위의 코드에서는 emp_record
라는 변수를 선언하여 커서에서 가져온 행을 저장합니다. FETCH
문을 사용하여 첫 번째 행을 가져오고, DBMS_OUTPUT.PUT_LINE
을 통해 직원의 이름을 출력합니다.
커서 닫기
작업이 끝난 후에는 커서를 닫아야 합니다. 커서를 닫기 위해서는 CLOSE
문을 사용합니다. 커서를 닫지 않으면 메모리 누수가 발생할 수 있습니다.
예제: 커서 닫기
CLOSE emp_cursor; -- 커서 닫기
전체 예제
다음은 커서를 선언하고 열고, 데이터를 가져오고, 마지막으로 닫는 전체 과정의 예제입니다.
DECLARE
CURSOR emp_cursor IS
SELECT first_name, last_name FROM employees;
emp_record emp_cursor%ROWTYPE; -- 커서의 행 타입을 가진 변수 선언
BEGIN
OPEN emp_cursor; -- 커서 열기
LOOP
FETCH emp_cursor INTO emp_record; -- 커서에서 행을 가져오기
EXIT WHEN emp_cursor%NOTFOUND; -- 더 이상 행이 없으면 종료
DBMS_OUTPUT.PUT_LINE(emp_record.first_name || ' ' || emp_record.last_name); -- 직원 이름 출력
END LOOP;
CLOSE emp_cursor; -- 커서 닫기
END;
이 예제에서는 커서를 통해 모든 직원의 이름을 출력하는 과정을 보여줍니다. 커서를 통해 데이터베이스에서 정보를 효율적으로 처리할 수 있는 방법을 이해할 수 있습니다.
명시적 커서와 암시적 커서의 차이
SQL에서 커서는 크게 명시적 커서(Explicit Cursor)와 암시적 커서(Implicit Cursor)로 나눌 수 있습니다. 이 두 가지 커서는 사용 방법과 제어 방식에서 차이가 있습니다. 각각의 특징을 이해하면 SQL 쿼리 결과를 처리하는 데 유용합니다.
명시적 커서 (Explicit Cursor)
명시적 커서는 개발자가 직접 선언하고 제어하는 커서입니다. 사용자가 커서를 열고, 데이터를 가져오며, 닫는 모든 과정을 명시적으로 수행합니다. 주로 PL/SQL 블록 내에서 사용되며, 복잡한 로직을 처리할 때 유용합니다.
예제: 명시적 커서 사용
DECLARE
CURSOR emp_cursor IS
SELECT first_name, last_name FROM employees;
emp_record emp_cursor%ROWTYPE; -- 커서의 행 타입을 가진 변수 선언
BEGIN
OPEN emp_cursor; -- 커서 열기
LOOP
FETCH emp_cursor INTO emp_record; -- 커서에서 행을 가져오기
EXIT WHEN emp_cursor%NOTFOUND; -- 더 이상 행이 없으면 종료
DBMS_OUTPUT.PUT_LINE(emp_record.first_name || ' ' || emp_record.last_name); -- 직원 이름 출력
END LOOP;
CLOSE emp_cursor; -- 커서 닫기
END;
위의 예제에서 emp_cursor
는 명시적 커서로, 사용자가 직접 선언하고 제어하고 있습니다.
암시적 커서 (Implicit Cursor)
암시적 커서는 SQL 문이 실행될 때 자동으로 생성되는 커서입니다. 사용자가 커서를 명시적으로 선언하거나 제어할 필요가 없으며, SQL 문이 실행될 때 Oracle DBMS가 자동으로 커서를 생성하고 결과를 처리합니다. 주로 단일 SQL 문을 실행할 때 사용됩니다.
예제: 암시적 커서 사용
BEGIN
FOR emp_record IN (SELECT first_name, last_name FROM employees) LOOP
DBMS_OUTPUT.PUT_LINE(emp_record.first_name || ' ' || emp_record.last_name); -- 직원 이름 출력
END LOOP;
END;
위의 예제에서는 FOR
루프를 사용하여 암시적 커서를 활용하고 있습니다. 사용자는 커서를 직접 선언하지 않고, SQL 문이 실행될 때 Oracle이 자동으로 커서를 생성합니다.
명시적 커서와 암시적 커서의 차이 요약
구분 | 명시적 커서 (Explicit Cursor) | 암시적 커서 (Implicit Cursor) |
---|---|---|
선언 | 개발자가 직접 선언하고 제어함 | 자동으로 생성되며 사용자가 제어하지 않음 |
사용 용도 | 복잡한 로직 처리 시 유용 | 단순한 SQL 문 실행 시 사용 |
제어 | OPEN, FETCH, CLOSE 문 사용 | 별도의 제어 없이 SQL 문 실행 시 자동 처리 |
이와 같이 명시적 커서는 사용자가 직접 제어하는 반면, 암시적 커서는 SQL 문이 실행될 때 자동으로 처리됩니다. 각 커서의 특성을 이해하고 적절한 상황에 맞게 사용하는 것이 중요합니다.
커서를 이용한 반복 처리
커서를 사용하면 데이터베이스의 결과 집합을 반복적으로 처리할 수 있습니다. 반복 처리는 여러 행을 하나씩 가져와서 특정 작업을 수행할 때 유용합니다. PL/SQL에서는 LOOP
구조를 사용하여 커서를 통해 반복적으로 데이터를 처리할 수 있습니다.
커서를 이용한 반복 처리의 기본 구조
- 커서 선언: 처리할 쿼리를 포함하는 커서를 선언합니다.
- 커서 열기:
OPEN
문을 사용하여 커서를 엽니다. - 데이터 가져오기:
FETCH
문을 사용하여 커서에서 행을 가져옵니다. - 반복 처리:
LOOP
구조를 사용하여 데이터를 반복적으로 처리합니다. - 커서 닫기: 작업이 완료되면
CLOSE
문으로 커서를 닫습니다.
예제: 커서를 이용한 반복 처리
다음 예제는 employees
테이블에서 모든 직원의 이름과 급여를 출력하는 방법을 보여줍니다.
DECLARE
CURSOR emp_cursor IS
SELECT first_name, last_name, salary FROM employees;
emp_record emp_cursor%ROWTYPE; -- 커서의 행 타입을 가진 변수 선언
BEGIN
OPEN emp_cursor; -- 커서 열기
LOOP
FETCH emp_cursor INTO emp_record; -- 커서에서 행을 가져오기
EXIT WHEN emp_cursor%NOTFOUND; -- 더 이상 행이 없으면 종료
DBMS_OUTPUT.PUT_LINE(emp_record.first_name || ' ' || emp_record.last_name || ': ' || emp_record.salary); -- 직원 이름과 급여 출력
END LOOP;
CLOSE emp_cursor; -- 커서 닫기
END;
코드 설명
- 커서 선언:
emp_cursor
라는 이름의 커서를 선언하고,employees
테이블에서 직원의 이름과 급여를 가져오는 쿼리를 정의합니다. - 커서 열기:
OPEN emp_cursor
문으로 커서를 엽니다. - 데이터 가져오기:
FETCH emp_cursor INTO emp_record
문을 사용하여 커서에서 행을 가져오고, 이를emp_record
변수에 저장합니다. - 반복 처리:
LOOP
구조 내에서DBMS_OUTPUT.PUT_LINE
을 사용하여 직원의 이름과 급여를 출력합니다.EXIT WHEN emp_cursor%NOTFOUND
문을 통해 더 이상 가져올 행이 없을 경우 반복을 종료합니다. - 커서 닫기: 모든 작업이 완료된 후
CLOSE emp_cursor
문으로 커서를 닫습니다.
주의사항
- 커서를 사용하여 반복 처리를 할 때는 항상 커서를 닫는 것을 잊지 말아야 합니다. 커서를 닫지 않으면 메모리 누수가 발생할 수 있습니다.
FETCH
문을 사용할 때는 항상NOTFOUND
속성을 체크하여 더 이상 데이터가 없을 경우 반복을 종료해야 합니다.
이와 같이 커서를 이용한 반복 처리는 SQL 쿼리의 결과를 효율적으로 처리할 수 있는 강력한 방법입니다.