DATABASE(oracleDB 11g)/PLSQL

[PL/SQL]명시적 커서 기초

SEUNGSAMI 2019. 2. 19. 14:21

명시적 커서 기초



###내용 보충 필요


다음의 예시는 결과가 전부 같다.


일반적인 커서

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DECLARE 
  CURSOR CUR_DEPT IS
    SELECT DEPTNO, DNAME, LOC, 0 AS SUM_SAL 
    FROM DEPT ; 
 
  REC_DEPT    CUR_DEPT%ROWTYPE ;   
BEGIN
    OPEN CUR_DEPT;
 
    LOOP
        FETCH CUR_DEPT INTO REC_DEPT;
        EXIT WHEN CUR_DEPT%NOTFOUND;
    
        SELECT SUM(SAL) INTO REC_DEPT.SUM_SAL 
        FROM EMP 
        WHERE DEPTNO = REC_DEPT.DEPTNO; 
    
        INSERT INTO COPY_DEPT VALUES REC_DEPT ; 
    END LOOP ; 
    
    CLOSE CUR_DEPT ; 
END ; 
/
cs


커서 FOR 루프

구문은 다음과 같다
1
2
3
4
5
FOR record_name IN cursor_name LOOP
    statement1;
    statement2;
    ...
END LOOP;
cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DECLARE 
  CURSOR CUR_DEPT IS   
    SELECT DEPTNO, DNAME, LOC, 0 AS SUM_SAL 
    FROM DEPT ; 
BEGIN 
    FOR REC_DEPT IN CUR_DEPT LOOP 
 
        SELECT SUM(SAL) INTO REC_DEPT.SUM_SAL 
      FROM EMP 
      WHERE DEPTNO = REC_DEPT.DEPTNO; 
    
      INSERT INTO COPY_DEPT VALUES REC_DEPT ; 
    END LOOP ; 
END ; 
/
cs


SUBQUERY를 사용하는 루프


1
2
3
4
5
6
7
8
9
10
11
12
BEGIN 
    FOR REC_DEPT IN (SELECT DEPTNO, DNAME, LOC, 0 AS SUM_SAL 
                     FROM DEPT) LOOP 
 
        SELECT SUM(SAL) INTO REC_DEPT.SUM_SAL 
      FROM EMP 
      WHERE DEPTNO = REC_DEPT.DEPTNO; 
    
      INSERT INTO COPY_DEPT VALUES REC_DEPT ; 
    END LOOP ; 
END ; 
/
cs


명시적 커서 속성

속성

유형

설명

%ISOPEN

Boolean

커서가 열려있으면 TRUE

%NOTFOUND

Boolean

가장 최근 패치가 행을 반환하지 않으면 TRUE

%FOUND

Boolean

가장 최근패치가 행을 반환하면 TRUE

%ROWCOUNT

Number

지금까지 반환된 총 행 수 



파라미터가 포함된 커서

구문은 다음과 같다.

1
2
3
4
CURSOR cursor_name
    [(parameter_name datatype, ...)]
IS
    select_statement;
cs


1
OPEN cursor_name(parameter_value,.....) ;
cs


다음 예시를 참고하자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
DECLARE
  V_DEPTNO NUMBER := &ID ;
 
  CURSOR c_emp_cursor  IS
    SELECT employee_id, last_name
    FROM employees
    WHERE department_id = V_DEPTNO;
 
  CURSOR c_emp_cursor_20  IS
    SELECT employee_id, last_name
    FROM employees
    WHERE department_id = 20;
    
    ...
BEGIN
  OPEN c_emp_cusor;
  OPEN c_emp_cursor_20;
cs



FOR UPDATE절

구문은 다음과 같다.

1
2
3
SELECT ...
FROM ...
FOR UPDATE [OF column_reference][NOWAIT | WAIT n];
cs


다음의 예시를 참고하자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DECLARE
    CURSOR CUR_EMP IS
        SELECT *
        FROM EMP
        FOR UPDATE-- LOCK을 걸어 놓는다.
BEGIN
    FOR REC_EMP IN CUR_EMP LOOP
        IF REC_EMP.SAL <=3000 THEN
            UPDATE EMP
            SET SAL = SAL*1.1
            WHERE CURRENT OF CUR_EMP;
           -- WHERE EMPNO = REC_EMP.EMPNO; 위의 WHERE절과 결과가 일치한다.
        END IF;
    END LOOP;
END;
/
cs


주의할 점으로는 작업을 하며 행이 LOCK이 되지 않으므로 다른 유저가 접근 할 수 있다.


SQL을 배운지 얼마 되지 않아 잘못된 내용이 있을 수 있습니다. 틀린 내용이있다면, 댓글로 달아주세요.