반응형

CURSOR

- SQL문을 처리한 결과를 담고 있는 영역(메모리영역)을 가리키는 일종의 포인터
- 처리 결과가 여러 개의 행으로 구해지는 SELECT문을 처리할 때 이용
- 사이클 : OPEN - FETCH - CLOSE
- FETCH문은 ResultSet(결과테이블)에서 로우(행=레코드) 단위로 데이터를 읽어들인다.
- FETCH 후에 CURSOR는 결과셋에서 다음행으로 이동한다.

- 상태 : 
%FOUND
: 커서 영역에 FETCH되지 않은 자료가 있다면 TRUE
%NOTFOUND
: 커서 영역의 데이터가 모두 FETCH되었다면 TRUE
%ISOPEN
: 커서가 OPEN된 상태이면 TRUE,
 묵시적커서는 OPEN상태 인식이 안 된다. 따라서 늘 FALSE
%ROWCOUNT
: 커서가 얻어 온 레코드의 개수
명시적커서 : DECLARE에 선언하는 커서들


SYNTAX
DECLARE
    CURSOR 커서이름 IS SELECT쿼리문 ; --명시적커서
    ex) CURSOR C_DEPT IS SELECT * FROM DEPT;
BEGIN
    OPEN 커서이름 [(매개변수,...)];
    FETCH 커서이름 INTO 변수이름 ;
    CLOSE 커서이름 ;
END ;
DECLARE 
    VDEPT DEPT%ROWTYPE;
    CURSOR C2 IS SELECT * FROM DEPT;
BEGIN
    DBMS_OUTPUT.PUT_LINE('부서번호/부서명/지역명');
    DBMS_OUTPUT.PUT_LINE('-------------------');
    
    OPEN C2;
    LOOP
        FETCH C2 INTO VDEPT.DEPTNO, VDEPT.DNAME, VDEPT.LOC;
        EXIT WHEN C2%NOTFOUND; --더 이상 읽어들일 FETCH가 없으면 TRUE
        DBMS_OUTPUT.PUT_LINE(VDEPT.DEPTNO||' '|| VDEPT.DNAME||''||VDEPT.LOC);
    END LOOP;
    
    DBMS_OUTPUT.PUT_LINE('행수 => '|| C2%ROWCOUNT);
    CLOSE C2;
END;

CURSOR와 FOR LOOP

- 반복할 때마다 CURSOR를 OPEN한 후,
행(레코드)을 인출(FETCH)한다.
- 모든 행이 처리되면 자동으로 CURSOR가 CLOSE된다.
- REVERSE불가 처리를 할 수 없다.

SYNTAX
FOR 레코드 IN 커서명 [(매개변수, ...)]
LOOP
    실행문;
END LOOP ;
 
   
ASDAS
묵시적 커서
DECLARE 
    V_DEPTNO EMP.DEPTNO%TYPE := 30; --NUMBER(4,0)
    V_EMP EMP%ROWTYPE ; --EMP테이블의 구조와 동일한 한 줄 자료형으로 데이터를 받아오는 참조자료형
BEGIN
    --묵시적 커서 : 여러 행의 데이터가 자동으로(묵시적으로) 처리됨.
    UPDATE EMP01
    SET SAL = SAL*1.01
    WHERE DEPTNO = V_DEPTNO;
    
    --SQL%ROWCOUNT : 커서명이 없을 경우 바로 전에 실행된 SQL문의 ROW수 반환하는 커서의 속성임.
    --커서명이 있는 경우 SQL부분을 커서명으로 넣을 수 있다.
    DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT);
    
    SELECT * INTO V_EMP FROM EMP01 WHERE ROWNUM = 1;
    DBMS_OUTPUT.PUT_LINE (SQL%ROWCOUNT);
END;
6
1

 

DECLARE 
    VDEPT DEPT%ROWTYPE;
    CURSOR C2 IS SELECT * FROM DEPT;
BEGIN
    DBMS_OUTPUT.PUT_LINE('부서번호/부서명/지역명');
    DBMS_OUTPUT.PUT_LINE('-------------------');
    
    OPEN C2;
    LOOP
        FETCH C2 INTO VDEPT.DEPTNO, VDEPT.DNAME, VDEPT.LOC;
        EXIT WHEN C2%NOTFOUND; --더 이상 읽어들일 FETCH가 없으면 TRUE
        DBMS_OUTPUT.PUT_LINE(VDEPT.DEPTNO||' '|| VDEPT.DNAME||''||VDEPT.LOC);
    END LOOP;
    
    DBMS_OUTPUT.PUT_LINE('행수 => '|| C2%ROWCOUNT);
    CLOSE C2;
END;
부서번호/부서명/지역명
-------------------
10 ACCOUNTINGNEW YORK
20 RESEARCHDALLAS
30 SALESCHICAGO
40 OPERATIONSBOSTON
행수 => 4
DECLARE
    V_EMPNO EMP.EMPNO%TYPE;
    V_ENAME EMP.ENAME%TYPE;
    
    CURSOR cur_emp( p_deptno EMP.DEPTNO%TYPE )
    IS
    SELECT EMPNO, ENAME FROM EMP WHERE DEPTNO = p_deptno;
BEGIN
    OPEN cur_emp (30);
    
    LOOP
    --커서에 선언 된 컬럼의 개수, 순서 자료형과
    --FETCH~INTO 절 안에 선언된 변수의 개수, 순서, 자료형이 일치해야 한다.
        FETCH cur_emp INTO V_EMPNO, V_ENAME;
        EXIT WHEN cur_emp%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE(V_EMPNO||' '||V_ENAME);
    END LOOP;
    CLOSE cur_emp;
END;
7499 ALLEN
7521 WARD
7654 MARTIN
7698 BLAKE
7844 TURNER
7900 JAMES
DECLARE 
    CURSOR C2 IS SELECT * FROM DEPT;
BEGIN
    DBMS_OUTPUT.PUT_LINE('부서번호/부서명/지역명');
    DBMS_OUTPUT.PUT_LINE('-------------------');
    
    FOR VDEPT IN C2 LOOP
        DBMS_OUTPUT.PUT_LINE(VDEPT.DEPTNO||' '|| VDEPT.DNAME||''||VDEPT.LOC);
    END LOOP;
END;
부서번호/부서명/지역명
-------------------
10 ACCOUNTINGNEW YORK
20 RESEARCHDALLAS
30 SALESCHICAGO
40 OPERATIONSBOSTON
AA
DECLARE 
    CURSOR cur_emp(p_deptno EMP.DEPTNO%TYPE)
    IS
    SELECT * FROM EMP WHERE DEPTNO = p_deptno;
BEGIN
    FOR emp_row IN cur_emp (30)
    LOOP
        DBMS_OUTPUT.PUT_LINE(emp_row.EMPNO||' '||emp_row.ENAME);
    END LOOP;
END;​
7499 ALLEN
7521 WARD
7654 MARTIN
7698 BLAKE
7844 TURNER
7900 JAMES
반응형

'[ORACLE]' 카테고리의 다른 글

[ORACLE] FUNCTION  (0) 2024.01.26
[ORACLE] PL/SQL - NDS  (1) 2024.01.25
[ORACLE] PL/SQL - LOOP, FOR LOOP, WHILE LOOP  (0) 2024.01.25
[ORACLE] IF ~ ELSIF~ ELSE조건문  (0) 2024.01.25
[ORACLE] REFERENCE TYPE - TYPE, ROWTYPE  (0) 2024.01.24

+ Recent posts