데이터베이스 커서
데이터베이스 커서(Cursor)는 일련의 데이터에 순차적으로 액세스할 때 검색 및 "현재 위치"를 포함하는 데이터 요소이다.
개요
[편집]일반적으로 데이터베이스는 같은 종류의 데이터를 많이 축적하고 있으며, 이용자가 요청하는 데이터는 1건 또는 여러 건이 될 수 있다. 이런 경우는 커서를 사용하여 다음과 같이 반복자의 요령으로 실현할 수 있다.
- 이용자는 검색 및 정렬 순서를 지정하여 커서를 정의한다.
- 매개 변수를 사용하는 경우 값을 결정하고 데이터 액세스를 시작한다.
- 커서 위치의 데이터를 검색한다. 검색 결과의 끝이라면 7에.
- 필요에 따라 커서 위치의 데이터를 변경, 삭제한다.
- 커서를 "다음 데이터"로 진행한다.
- 3 반복.
- 반복 종료 후 커서를 풀어 놓는다.
시스템에 따라 5에서 다음 데이터를 계속 이외에 하나 전의 데이터로 돌아가는 것도 허용하고 있다.
실제 예
[편집]SQL
[편집]관계 데이터베이스의 질의어로 널리 사용되고 있는 SQL에서 커서를 이용한 접근을 위해 일련의 문을 제공하고 있다. "DECLARE CURSOR"에서 커서를 선언하고, "FETCH"에서 커서 위치의 데이터를 검색하는 것과 동시에 다음 데이터로 이동한다. 데이터 변경 "UPDATE" 또는 제거 "DELETE"는 "WHERE CURRENT OF 커서 이름"을 지정하여 커서 위치의 데이터를 조작할 수 있다. 사용 후는 " CLOSE "로 풀어 놓는다. 구체적인 문법은 SQL#커서 정의 및 사용을 참조.
ODBC
[편집]C 언어 프로그램에서 SQL을 사용하여 데이터베이스에 액세스하기 위한 라이브러리의 하나로 ODBC가 있다. ODBC는 Microsoft Windows에서 대폭적인 업그레이드 이후, 업계 표준의 SQL / CLI 및 JDBC의 기반이 되었다. 커서 조작에 따른 SQL 문은 다음과 같이 개별 ODBC 함수가 대응하고 있다.
ODBC 함수 | 해당 SQL 구문 |
---|---|
SQLPrepare | DECLARE CURSOR
|
SQLExecute | OPEN
|
SQLFetch | FETCH
|
SQLFreeStmt | CLOSE
|
ODBC는 응용 프로그램 프로그램이 커서를 직접 지정하는 것은 거의 없다. 위의 함수는 모두 "구문 핸들"( Statement Handle)을 인수하고, 이 핸들이 가리키는 데이터 구조에 커서가 포함되어 있다고 취급한다. 즉 구문 핸들이 이터레이터의 역할을 하고 있다.
주의
[편집]- 커서는 실행중인 검색 및 현재 위치를 유지하기 위해, 메모리 등의 많은 자원을 필요로 한다. 커서 해방 누출, 메모리 누수로 이어질 수 있다.
- 표준 SQL 규격에서는 트랜잭션을 종료하면 커서가 삭제되는 사양이다. 그러나 DBMS는 삭제되지 않고 그대로 데이터에 액세스할 수 있다. 표준 SQL 규격에 의한 사용을 하는 경우 트랜잭션 종료 후 커서를 삭제해야 한다.
예
[편집]EMPLOYEES 테이블
SQL> desc EMPLOYEES_DETAILS;
Name Null? Type
----------------------------------------- -------- --------------------
EMPLOYEE_ID NOT NULL NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL VARCHAR2(25)
EMAIL NOT NULL VARCHAR2(30)
PHONE_NUMBER VARCHAR2(20)
HIRE_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
SALARY NUMBER(8,2)
COMMISSION_PCT NUMBER(2,2)
MANAGER_ID NUMBER(6)
DEPARTMENT_ID NUMBER(4)
SAMPLE CURSOR KNOWN AS EE
CREATE OR REPLACE
PROCEDURE EE AS
BEGIN
DECLARE
v_employeeID EMPLOYEES_DETAILS.EMPLOYEE_ID%TYPE;
v_FirstName EMPLOYEES_DETAILS.FIRST_NAME%TYPE;
v_LASTName EMPLOYEES_DETAILS.LAST_NAME%TYPE;
v_JOB_ID EMPLOYEES_DETAILS.JOB_ID%TYPE:= 'IT_PROG';
Cursor c_EMPLOYEES_DETAILS IS
SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME
FROM EMPLOYEES_DETAILS
WHERE JOB_ID ='v_JOB_ID';
BEGIN
OPEN c_EMPLOYEES_DETAILS;
LOOP
FETCH c_EMPLOYEES_DETAILS INTO v_employeeID,v_FirstName,v_LASTName;
DBMS_OUTPUT.put_line(v_employeeID);
DBMS_OUTPUT.put_line(v_FirstName);
DBMS_OUTPUT.put_line(v_LASTName);
EXIT WHEN c_EMPLOYEES_DETAILS%NOTFOUND;
END LOOP;
CLOSE c_EMPLOYEES_DETAILS;
END;
END;