정의 ● 명시 적 커서 는 하나 이상 의 행 을 액세스 하 는 SELECT 명령문 을 처리 하 기 위해서 사용 ● 선 언부 에서 명시 적 으로 커서 선언 ● 명시 적 커서 는 블록 의 실행 부 에서 커서 조작 명령 을 통해 처리 ● 명령 을 이용 하 여 질의 에 의해 반환 된 행 들 을 한 번 에 한 행 씩 처리 ● 커서 선언 은 선 언부 에서 , 커서 OPEN , FETCH , CLOSE 정의 는 실행 부 에서 정의 처리 과정 ① 커서 선언 ( DECLARE CURSOR 절 ) : 커서 는 공유 풀 내 의 전용 SQL 영역 에 생 성 ② 커서 열기 ( OPEN 절 ) : 커서 를 활성 화 하 여 커서 와 연관 된 SELECT 명령문 실행 ③ 데 이타 추출 ( FETCH 절 ) : SELECT 명령문 에 의해 검색 된 행 중 에서 커서 가 가리키 는 행 을 액세스 ④ 커서 닫 기 ( CLOSE 절 ) : 오픈 된 커서 를 비활성 화 커서 선언 ● 커서 를 선언 하 고 , 커서 와 관련 된 SELECT 명령문 정의 ● SELECT 문장 에 는 INTO 절 을 사용 하 지 않 음 ● INTO 절 은 실행 부 의 FETCH 명령문 에서 사용 ● 커서 선언 부분 에서 지역 변수 나 전역 변수 사용 가능 ● 커서 정의 에서 사용 되 는 지역 변수 나 전역 변수 는 반드시 커서 선언 전 에 정의 필요 ● 변수 는 컬럼 명과 다르 게 선언 ☞ 사용법 DECLARE CURSOR cursor ISselect _ statement ;☞ 사용 예 DECLARECURSOR Cursor _ Emp ISSELECT ename , deptnoFROM empWHERE sal > 2000 ; 커서 열기 ( OPEN ) ● 공유 풀 의 라이브러리 캐 쉬 에 설정 된 커서 영역 을 오픈 ● 선언 된 커서 와 연관 된 SELECT 명령문 을 실행 하 여 active set 을 구성 ● 커서 는 검색 된 행 으로 구성 된 active set 중 에서 첫 번 째 행 을 가르킴 ● 실행 과정 - 구문 분석 ( Parsing ) : 문장 이나 의미 , 권한 등 이 제대로 되 어 있 는지 검사 - 바인딩 ( Binding ) : 변수 의 값 을 할당 - 실행 ( Excute ) : 라이브러리 캐 쉬 에 할당 된 커서 영역 을 오픈 하 고 active set 구성 ☞ 사용법 OPEN cursor ;☞ 사용 예 OPEN Cursor _ Emp ; 데 이타 추출 ( FETCH ) ● 현재 커서 가 가르키 는 행의 값 을 변수 로 할당 하 는 과정 ● 커서 선언 시 사용 한 SELECT 명령문 의 컬럼 개수 와 데 이타 타입 이 FECTH ∼ INTO 절 의 변수 개수 , 데 이타 타입 과 동일 해야 함 ☞ 사용법 FETCH cursor INTO variable _ list ;● variable _ list - 현재 검색 된 결과 행 을 저장 하 기 위한 변수 리스트 - variable _ list 변수 의 개수 는 커서 선 언부 에서 정의 한 SELECT 문장 의 컬럼 개수 와 동일 - 커서 안 에서 PL / SQL 레코드 타입 설정 이 가능 하 며 , variable _ list 에 도 사용 가능 ☞ 사용 예 FETCH Cursor _ Emp INTO v _ ename , v _ deptno ; 커서 닫 기 ( CLOSE ) ● 현재 오픈 된 커서 를 닫 음 ● 커서 오픈 ( OPEN ) 명령문 에 의해 할당 된 커서 영역 반환 ● 현재 커서 를 닫 은 후 에 다시 해당 커서 를 오픈 가능 ☞ 사용법 CLOSE cursor _ name ;☞ 사용 예 CLOSE Cursor _ Emp ;▶ 명시 적 커서 수행 방법 커서 속성 ● 커서 상태 를 검사 하 기 위해 제공 되 는 네 가지 속성 ● SQL 명령문 에서 커서 속성 을 직접 참조 할 수 없 음 구 분 타입 내 용 % ROWCOUNTNumber · 현재 까지 FETCH 된 행의 갯 수 % FOUNDBoolean · FETCH 할 행이 존재 할 경우 값 은 TRUE % NOTFOUNDBoolean · FETCH 할 올 행 이 없 을 경우 값 은 TRUE % ISOPENBoolean · 커서 가 오픈 되 어 있 을 경우 값 은 TRUE ☞ 사용 예 : % ROWCOUNTOPEN Cursor _ Emp ; LOOPFETCH Cursor _ Emp INTO v _ emp , v _ deptno ; EXIT WHEN Cursor _ Emp % ROWCOUNT >= 5 ; END LOOP ; CLOSE Cursor _ Emp ;☞ 사용 예 : % NOTFOUND OPEN Cursor _ Emp ; LOOPFETCH Cursor _ Emp INTO v _ emp , v _ deptno ; EXIT WHEN Cursor _ Emp % NOTFOUND ; END LOOP ; CLOSE Cursor _ Emp ;☞ 사용 예 : % ISOPEN IF NOT Cursor _ Emp % ISOPEN THENOPEN Cursor _ Emp ; END IF ;☞ 커서 를 사용 한 프로 시 져 생 성 실습 ☞ 프로 시 져 생 성 SQL > CREATE OR REPLACE PROCEDURE cur _ exam ( v _ sal IN number ) ISv _ ename emp . ename % TYPE ; v _ dname dept . dname % TYPE ; CURSOR Cursor _ Emp ISSELECT ename , dnameFROM emp e , dept dWHERE e . deptno = d . deptnoAND e . sal > v _ sal ; BEGINOPEN Cursor _ Emp ; IF NOT Cursor _ Emp % ISOPEN THENOPEN Cursor _ Emp ; END IF ; DBMS _ OUTPUT . PUT _ LINE ( ' 다음 은 4 월 승진 자 명단 입니다 . '); LOOP FETCH Cursor _ Emp INTO v _ ename , v _ dname ; EXIT WHEN Cursor _ Emp % ROWCOUNT >= 5 OR Cursor _ Emp % NOTFOUND ; DBMS _ OUTPUT . PUT _ LINE ( v _ dname ||' 부서 의 '|| v _ ename ||' 씨 '); END LOOP ; CLOSE Cursor _ Emp ; DBMS _ OUTPUT . PUT _ LINE ( ' 발령일 은 4 월 1 일 입니다 . '); DBMS _ OUTPUT . PUT _ LINE ( ' *^^* 만우절 행사 였 습니다 . '); END cur _ exam ;/ Procedure created . ☞ DBMS _ OUTPUT . PUT _ LINE 을 사용 하 기 위해 SERVEROUTPUT 환경 변수 를 on 상태 로 설정 SQL > SET SERVEROUTPUT on ☞ 실행 및 출력 결과 SQL > EXEC cur _ exam ( 2500 ) ; 다음 은 4 월 승진 자 명단 입니다 . ACCOUNTING 부서 의 KING 씨 RESEARCH 부서 의 KEBIN 씨 RESEARCH 부서 의 SCOTT 씨 RESEARCH 부서 의 LEE 씨 발령일 은 4 월 1 일 입니다 . *^^* 만우절 행사 였 습니다 . PL / SQL procedure successfully completed . CURSOR FOR 루프 절 ● PL / SQL 의 선 언부 에 이미 명시 적 커서 가 선언 되 어 있 어야 함 ● FOR 루프 가 초기 화 될 때 내부 적 으로 커서 가 오픈 ● FOR 루프 가 반복 될 때 마다 커서 가 가르키 는 행 을 액세스 ● 루프 는 마지막 행 을 추출 한 후 자동 적 으로 FOR 루프 를 종료 ● OPEN , FETCH , CLOSE 의 기능 을 하나 의 FOR 루프 에서 실행 가능 ☞ 사용법 FOR record _ name IN cursor _ name LOOPstatement 1 ; statement 2 ;.................. END LOOP ;● record _ name : 내부 적 으로 선언 한 레코드 ● cursor _ name : 선 언부 에서 이미 선언 한 커 서명 ☞ 사용 예 ☞ 프로 시 져 생 성 SQL > CREATE OR REPLACE PROCEDURE cur _ for ( dnum IN NUMBER ) ISCURSOR emp _ cur ISSELECT sal , commFROM empWHERE deptno = dnum ; total NUMBER : = 0 ; high _ paid NUMBER : = 0 ; high _ comm NUMBER : = 0 ; BEGINFOR emp _ rec IN emp _ cur LOOPemp _ rec . comm : = NVL ( emp _ rec . comm , 0 ) ; total : = total + emp _ rec . sal + emp _ rec . comm ; IF emp _ rec . sal > 2000 THENhigh _ paid : = high _ paid + 1 ; END IF ; IF emp _ rec . comm > emp _ rec . sal THENhigh _ comm : = high _ comm + 1 ; END IF ; END LOOP ; DBMS _ OUTPUT . PUT _ LINE ( ' 1 . 전체 : ' || total ) ; DBMS _ OUTPUT . PUT _ LINE ( ' 2 . $ 2000 이상 받 는 사원수 : '|| high _ paid ) ; DBMS _ OUTPUT . PUT _ LINE ( ' 3 . 월급 보다 커미션 이 더 많 은 사원수 : '|| high _ comm ) ; END cur _ for ;/ Procedure created . ☞ 현재 데 이타 확인 SQL > select sal , comm from emp where deptno = 30 ; SALCOMM ----------------- 1600300125014002850 15000950 ☞ 실행 및 출력 결과 SQL > EXEC cur _ for ( 30 ) ; 1 . 전체 : 98502 . $ 2000 이상 받 는 사원수 : 13 . 월급 보다 커미션 이 더 많 은 사원수 : 1 PL / SQL procedure successfully completed . FOR UPDATE 절 ● FOR UPDATE 절 을 사용 한 트랜잭션 이 완료 되 기 전 까지 테이블 에 액세스 하 지 못하 도록 명시 적 으로 락 을 생성 하 는 방법 ● update 나 delete 명령 수행 전 에 대상 행 에 대해 락 을 생성 하 고자 할 때 사용 ☞ 사용법 SELECT . .. FROM . .. FOR UPDATE [ OF column _ reference ] [ NOWAIT ] ;● 질의 한 결과 행 이 다른 세션 에 의해 이미 락 이 걸려 있 다면 , 즉시 오라클 에러 를 반환 ● NOWAIT 명령 을 사용 하 지 않 으면 다른 세션 에 의한 락 이 풀릴 때 까지 기다림 ☞ 사용 예 : update , delete 문장 에 의해 사용 될 deptno 가 10 인 사원 의 행 을 질의 하 면서 해당 행 에 대해 락 을 생 성 DECLARECURSOR emp _ cursor ISSELECT empno , ename , salFROM empWHERE deptno = 10 FOR UPDATE OF sal NOWAIT ; WHERE CURRENT OF 절 ● 커서 를 이용 하 여 가장 최근 에 검색 된 행 을 삭제 또는 수정 하 는 경우 에 사용 ● 커서 를 선언 할 때 FOR UPDATE 절 이 반드시 있 어야 함 ● WHERE CURRENT OF 절 에 의해 지정 된 커서 는 가장 최근 에 FETCH 한 행 을 가르킴 ☞ 사용 예 ☞ 프로 시 져 생 성 SQL > CREATE OR REPLACE PROCEDURE cur _ whereISCURSOR emp _ cur ISSELECT ename , rowidFROM empWHERE deptno = 30 FOR UPDATE ; v _ ename emp . ename % TYPE ; v _ rowid ROWID ; BEGINOPEN emp _ cur ; LOOPFETCH emp _ cur INTO v _ ename , v _ rowid ; EXIT WHEN emp _ cur % NOTFOUND ; UPDATE empSET sal = sal * 2 WHERE CURRENT OF emp _ cur ;-- 보통 은 UPDATE emp SET sal = sal * 2 WHERE rowid = v _ rowid ;-- 이나 UPDATE emp SET sal = sal * 2 WHERE ename = v _ ename ; 로 -- 표현 함 . END LOOP ; CLOSE emp _ cur ; COMMIT ; END ;/ Procedure created . 매개변수 가 있 는 커서 선언 ● 커서 선언 시 매개변수 사용 가능 ● 매개변수 의 데 이타 타입 은 스칼라 변수 와 동일 하 고 크기 지정 은 불 가능 ● 매개변수 는 커서 와 관련 된 SELECT 명령문 에서 참조 하 기 위해 사용 ● 커서 가 오픈 될 때 커서 에 매개변수 값 을 전달 하 여 질의 내 에서 사용 ☞ 사용법 CURSOR cursor _ name [ parameter datatype , . ..)] ISselect _ statement ;☞ 사용 예 CURSOR emp _ cur ( dnum number ) ISSELECT sal , commFROM empWHERE deptno = dnum ; BEGINFOR emp _ rec IN emp _ cur ( 30 ) LOOP . .. - 매개변수 가 있 는 커서 를 선언 하 면 매개변수 의 값 이 바뀔 때 마다 질 의 조건 이 바뀌 므로 여러 개 의 커서 를 선언 하 는 것 과 동일 한 효과 를 얻 을 수 있 음 출처 : http : / / www . dbcore . net / ~ corenet / education / speciallec / sqlplsql / chap 15 - 3 . html