오라클 명시적 커서(Explicit Cursor)
멀티 로우를 SELECT 하기위해 사용한다. 선언(Declaring) : Declare 섹션에서 정의한다. 메모리 초기화 단계이며 커서에 이름을 부여하고 SELECT문장을 정의하며, SELECT문에는 INTO 절이 필요없다. CURSOR c_emp IS SELECT * FROM emp; 오픈(Opening) : SQL문장을 실행하고 커서를 위한 메모리를 할당하며 BEGIN 절에서 실행한다. 커서는 SELECT된 데이터(Active Set)의 첫번째 레코드에 포인터가 위치하고 패치단계에서 사용할 수 있게 된다. OPEN시 실행되는 SQL문장에서 추출되는 레코드가 없더라도 오류가 발생하지 않고 데이터가 없다는 것은 이후 FETCH를 마친 후 커서 속성값을 통해 판단 할 수 있다.(%FOUND) OPEN c_emp; 패치(Fetching) : 데이터 추출단계이며 FETCH되는 레코드가 없더라도 오류가 발생하지 않는다. INTO절 다음에 오는 칼럼 리스트는 SELECT시 정의한 칼럼 리스트와 개수, 타입이 동일해야 한다. “SELECT *” 등으로 커서를 만들었다면 %ROWTYPE을 적절히 이용하면 된다. FETCH c_emp INTO c_emp_record; 종료(Closing) : 커서 Closing CLOSE c_emp; [명시적 커서의 속성] 커서이름%ISOPEN : 커서가 오픈되었으면 TRUE 커서이름%FOUND : FETCH했는데 레코드가 있었으면 TRUE 커서이름%NOTFOUND : FETCH했는데 레코드가 없었으면 TRUE 커서이름%ROWCOUNT : 지금까지 FETCH한 데이터 건수 %FOUND %ISOPEN %NOT FOUND %ROWCOUNT OPEN 전 오류 FALSE 오류 오류 후 NULL TRUE NULL 0 First FETCH 전 NULL TRUE NULL 0 후 TRUE TRUE FALSE 1 Next FETCH(es) 전 TRUE TRUE FALSE 1 후 TRUE TRUE FALSE 패치한 건수 Last FETCH 전 TRUE TRUE FALSE 패치한 건수 후 FALSE TRUE TRUE 패치한 건수 CLOSE 전 FALSE TRUE TRUE 패치한 건수 후 오류 FALSE 오류 오류 SQL> SET SERVEROUTPUT ON SQL> DECLARE CURSOR c_emp IS SELECT ename, sal FROM emp WHERE deptno = 10; v_ename emp.ename%TYPE; v_sal emp.sal%TYPE; BEGIN OPEN c_emp; LOOP FETCH c_emp INTO v_ename, v_sal; EXIT WHEN c_emp%NOTFOUND OR c_emp%NOTFOUND IS NULL; DBMS_OUTPUT.PUT_LINE(c_emp%ROWCOUNT || '. ' || v_ename || ',' || v_sal); END LOOP; CLOSE c_emp; END; / 1. CLARK,2837 2. KING,5789 3. MILLER,1505 -- CURSOR FOR LOOP는 커서의 레코드를 알아서 다 처리해주므로 EXIT WHEN이 필요없다 -- 알아서 OPEN하고 알아서 FETCH, Closing 한다. 즉 선언만 하여 사용하면 된다. SQL> DECLARE CURSOR c_emp IS SELECT ename, sal FROM emp WHERE deptno = 10; BEGIN FOR emp_record IN c_emp LOOP DBMS_OUTPUT.PUT_LINE(c_emp%ROWCOUNT || '. ' || emp_record.ename || ',' || emp_record.sal); END LOOP; END; / 1. CLARK,2837 2. KING,5789 3. MILLER,1505 -- 아래와 같이 커서 정의를 CURSOR FOR LOOP헤더에서 해도 된다. -- 물론 커서이름이 없으니 커서의 속성은 사용하지 못한다. SQL> DECLARE BEGIN FOR emp_record IN (SELECT ename, sal FROM emp WHERE deptno = 10) LOOP DBMS_OUTPUT.PUT_LINE(emp_record.ename || ',' || emp_record.sal); END LOOP; END; / CLARK,2837 KING,5789 MILLER,1505 |
2015년 9월 3일 목요일
오라클 명시적 커서(Explicit Cursor)
피드 구독하기:
댓글 (Atom)
댓글 없음:
댓글 쓰기