커서(데이터베이스)
Cursor (databases)![]() |
컴퓨터 과학에서 데이터베이스 커서는 데이터베이스의 레코드에 대한 통과를 가능하게 하는 메커니즘이다. 커서는 데이터베이스 레코드의 검색, 추가 및 제거와 같은 트래버설과 함께 후속 처리를 용이하게 한다. 트래버설의 데이터베이스 커서 특성은 커서를 반복기의 프로그래밍 언어 개념과 유사하게 만든다.
커서는 데이터베이스 프로그래머가 데이터베이스 시스템 쿼리에 의해 반환된 개별 행을 처리하는 데 사용된다. 커서를 사용하면 전체 결과 세트를 한 번에 조작할 수 있다. 이 시나리오에서 커서는 결과 집합의 행을 순차적으로 처리할 수 있다.
SQL 프로시저에서 커서는 결과 집합(데이터 행 집합)을 정의하고 행별로 복잡한 로직을 수행할 수 있도록 한다. 동일한 메카닉을 사용함으로써 SQL 프로시저는 결과 집합을 정의하고 SQL 프로시저의 호출자 또는 클라이언트 애플리케이션으로 직접 반환할 수도 있다.
커서는 행 집합의 한 행에 대한 포인터로 볼 수 있다. 커서는 한 번에 한 행만 참조할 수 있지만 필요에 따라 결과 집합의 다른 행으로 이동할 수 있다.
사용법
SQL 프로시저에서 커서를 사용하려면 다음을 수행해야 한다.
- 결과 집합을 정의하는 커서를 선언하십시오.
- 결과 세트를 설정하려면 커서를 여십시오.
- 데이터를 한 번에 한 행씩 커서에서 필요에 따라 로컬 변수에 가져오십시오.
- 완료되면 커서를 닫으십시오.
커서로 작업하려면 다음 SQL 문을 사용하십시오.
이 절에서는 SQL:2003 표준이 내장된 SQL의 응용 프로그램에서 커서를 사용하는 방법을 정의하는 방법을 소개한다. 관계형 데이터베이스 시스템의 모든 애플리케이션 바인딩이 이 표준을 준수하는 것은 아니며, 일부(예: CLI 또는 JDBC)는 다른 인터페이스를 사용한다.
프로그래머는 다음을 사용하여 DBMS에 커서를 알린다. DECLARE
... CURSOR
명령문 및 커서 이름 할당:
Cursor_name Cursor Is SELECT ... From ...을 선언하십시오.
코드가 데이터에 액세스하기 전에 먼저 커서를 OPEN
명세서 성공적인 오프닝 직후, 커서는 결과 집합의 첫 번째 행 앞에 배치된다.
OPEN cursor_name
애플리케이션은 로 설정된 결과의 특정 행에 커서를 위치시킨다. FETCH
명세서 가져오기 작업은 행의 데이터를 응용프로그램으로 전송한다.
FETCH cursor_name INT...
응용 프로그램이 사용 가능한 모든 행을 처리하거나 가져오기 작업을 존재하지 않는 행(아래에서 비교 스크롤 가능 커서)에 배치하면, DBMS는 결과 집합의 끝을 나타내기 위해 SQLSTATE '02000'(일반적으로 SQLCODE +100과 함께)을 반환한다.
마지막 단계에는 다음 명령을 사용하여 커서를 닫는 작업이 포함된다. CLOSE
문:
CLOSE cursor_name
커서를 닫은 후 프로그램이 다시 커서를 열 수 있는데, 이는 DBMS가 동일한 쿼리 또는 다른 쿼리를 재평가하여 새로운 결과 집합을 구축함을 의미한다.
스크롤 가능 커서
프로그래머는 커서를 스크롤 가능 또는 스크롤 불가능으로 선언할 수 있다. 스크롤 가능은 커서가 이동할 수 있는 방향을 나타낸다.
비스크롤 가능(또는 전진 전용) 커서를 사용하면 FETCH
각 행은 최대 한 번에, 커서는 자동으로 다음 행으로 이동한다. 마지막 행을 가져온 후 다시 가져오면 마지막 행 뒤에 커서를 놓고 SQLSTATE 02000(SQLCODE +100) 코드를 받는다.
프로그램은 다음 기능을 사용하여 결과 집합의 아무 곳에나 스크롤 가능한 커서를 배치할 수 있다. FETCH
SQL 문. 커서를 선언할 때 키워드 SCRAN을 지정해야 한다. 기본값은 NO SCROLL
그러나 JDBC와 같은 다른 언어 바인딩은 다른 기본값을 적용할 수 있다.
CRESTALL cursor_name sensitivity Scroll cursor for SELECT ... FROM ...
스크롤 가능 커서의 대상 위치는 (현재 커서 위치에서) 상대적으로 지정하거나 (결과 집합의 시작에서) 절대적으로 지정할 수 있다.
커서_name에서 [다음 이전 첫 번째 마지막 ] 가져오기
Cursor_name에서 절대 n 가져오기
Cursor_name에서 FETCH RENTERNERN n;
스크롤 가능한 커서는 결과 집합의 동일한 행에 여러 번 액세스할 수 있다. 따라서 다른 트랜잭션의 데이터 수정(삽입, 업데이트, 삭제 작업)은 결과 집합에 영향을 미칠 수 있다. 커서는 그러한 데이터 수정 시 민감하거나 무감각할 수 있다. 민감한 커서는 커서의 결과 집합에 영향을 미치는 데이터 수정을 선택하지만, 무감각한 커서는 그렇지 않다. 또한 커서는 INFLUNSID일 수 있으며, 이 경우 DBMS는 가능한 한 민감도를 적용하려고 한다.
"WITH HOLD"
커서는 일반적으로 트랜잭션 종료 시 자동으로 닫힌다. 즉, 커밋 또는 롤백(또는 트랜잭션의 암묵적 종료)이 발생할 때 닫힌다. 이 동작은 커서를 WITH HOLD 절(기본값은 홀드 없음)으로 선언할 경우 변경될 수 있다(일부 DBMS는 이 표준 동작에서 벗어나고 홀드 가능한 커서를 ROLLBOW로 열 때 닫힌다).
Cursor_name Cursor 홀드 for SELECT... FROM ....
커밋이 발생하면 다음 행 앞에 고정 가능한 커서가 위치한다. 따라서, 위치된 업데이트 또는 위치된 DELETE 문은 거래에서 FETCH 작업이 먼저 발생한 후에만 성공한다.
JDBC는 커서를 기본값별로 고정 가능한 커서로 정의한다는 점에 유의하십시오. 이는 JDBC가 기본값별로 자동 커밋도 활성화하기 때문에 수행된다.
배치한 업데이트/삭제 문
커서는 DBMS의 데이터를 응용프로그램으로 가져오는 데 사용될 뿐만 아니라 업데이트 또는 삭제할 테이블의 행을 식별하는 데도 사용할 수 있다. SQL:2003 표준은 위치 업데이트를 정의하고 위치 삭제 SQL 문을 정의한다. 그러한 문장은 술어가 있는 일반적인 WHERE 절을 사용하지 않는다. 대신 커서가 행을 식별한다. 커서는 다음 방법으로 열어서 이미 행에 배치해야 한다. FETCH
명세서
업데이트 table_name SET... 여기서 cursor_name의 현재 위치
테이블에서 삭제_name 여기서 cursor_name
위치 업데이트 또는 삭제 문을 성공적으로 실행하려면 커서가 업데이트 가능한 결과 집합에서 작동해야 한다. 그렇지 않으면 DBMS는 데이터 변경사항을 커서에 언급된 기본 테이블에 적용하는 방법을 모를 것이다.
분산 트랜잭션의 커서
트랜잭션 모니터를 사용하여 제어되는 분산 트랜잭션(X/Open XA Environments)에서 커서를 사용하는 것은 분산되지 않은 트랜잭션에서 커서와 다르지 않다.
그러나 고정 가능한 커서를 사용할 때는 주의를 기울여야 한다. 연결은 다른 애플리케이션에서 사용할 수 있다. 따라서 일단 트랜잭션이 종료되고 커밋되면 후속 트랜잭션(다른 애플리케이션에서 실행 중)은 기존의 고정 가능한 커서를 상속할 수 있다. 따라서 애플리케이션 개발자는 이러한 상황을 인지해야 한다.
XQuery의 커서
XQuery 언어는 반복() 함수를 사용하여 커서를 만들 수 있다.
형식:
하게 하다 $진열된 := 부속의($결과, $출발하다, $항목 수)
$결과가 초기 XQuery의 결과인 경우 $start는 시작할 항목 번호, $item-count는 반환할 항목 수입니다.
이와 동등하게 이는 술어를 사용하여 수행할 수도 있다.
하게 하다 $진열된 := $결과[$출발하다 로 $종지부를 찍다]
어디에 $end
마지막 순서야
전체 예는 Wikibooks에서 XQuery/Searching, Paging 및 Sorting#Paging을 참조하십시오.
커서의 단점
다음 정보는 특정 데이터베이스 시스템에 따라 달라질 수 있다.
커서로부터 행을 가져오면 매번 네트워크 라운드 트립이 발생할 수 있다. 이것은 일반적으로 DELETE와 같은 단일 SQL 문을 실행하는 데 필요한 것보다 훨씬 더 많은 네트워크 대역폭을 사용한다. 네트워크 라운드 트립이 반복되면 커서를 이용한 작업 속도가 크게 저하될 수 있다. 일부 DBMS는 블록 가져오기를 사용하여 이 효과를 줄이려고 한다. 블록 가져오기란 여러 행이 서버에서 클라이언트로 함께 전송됨을 의미한다. 클라이언트는 전체 행 블록을 로컬 버퍼에 저장하고 버퍼가 소진될 때까지 행을 검색한다.
커서는 잠금, 패키지, 프로세스 및 임시 저장소와 같은 서버의 리소스를 할당한다. 예를 들어, Microsoft SQL Server는 임시 테이블을 생성하고 쿼리의 결과 집합으로 채워 커서를 구현한다. 커서가 제대로 닫히지 않은 경우(할당되지 않음) SQL 세션(연결) 자체가 닫힐 때까지 리소스가 해제되지 않는다. 이러한 서버의 자원 낭비는 성능 저하와 실패로 이어질 수 있다.
예
직원 테이블
SQL> 설명하다 직원_상세; 이름 Null? 유형 ----------------------------------------- -------- -------------------- 직원_ID null 번호가 아님(6) First_NAME VARCHAR2(20) Last_NAME NULL VARCHAR2(25)가 아님 NULL VARCHAR2(30)가 아닌 이메일 Phone_NUMBER VARCHAR2(20) 렌트_날짜가 null이 아닌 날짜 JOB_ID NULL VARCHAR2(10)가 아님 급여 번호(8,2) 커미션_PCT 번호(2,2) 관리자_ID 번호(6) 부서_ID 번호(4)
샘플 커서 알려진 AS EE 만들다 OR 교체 절차 EE AS 시작 선언하다 v_properties아이디 직원_상세.사원_아이디%TYPE; v_FirstName 직원_상세.퍼스트_NAME%TYPE; v_LASTName 직원_상세.Last_NAME%TYPE; v_JOB_ID 직원_상세.JOB_ID%TYPE:= 'IT_PROG'; 커서 c_EMENTES_DETILS IS 선택 사원_아이디, 퍼스트_NAME, Last_NAME From. 직원_상세 어디에 JOB_ID ='v_JOB_ID'; 시작 오픈 c_EMENTES_DETILS; 루프 FETCH c_EMENTES_DETILS INO v_properties아이디,v_FirstName,v_LASTName; DBMS_OUTPUT.put_line(v_properties아이디); DBMS_OUTPUT.put_line(v_FirstName); DBMS_OUTPUT.put_line(v_LASTName); 종료 언제 c_EMENTES_DETILS%notfound; 끝 루프; 가까운. c_EMENTES_DETILS; 끝; 끝;
참고 항목
참조
- 크리스토퍼 J. 데이트: 심층 데이터베이스, 오라일리 & 어소시에이츠, ISBN0-596-10012-4
- 토마스 M. 코널리, 캐롤린 E. 베그: 데이터베이스 시스템, 애디슨-웨슬리, ISBN 0-321-21025-5
- 라미즈 엘마스리, 샴칸트 B. 나바타: 데이터베이스 시스템의 기본 원리, 애디슨 웨슬리, ISBN 0-201-54263-3
- 닐 매튜, 리처드 스톤스: Postgre를 사용하여 데이터베이스 시작SQL: 초보에서 프로페셔널, 어프레스 ISBN 1-59059-478-9
- 토마스 키테: 전문가 일대일: Oracle, Apress, ISBN 1-59059-525-4
- 케빈 로니: Oracle Database 10g: 전체 참조 자료, Oracle Press, ISBN 0-07-225351-7