[오라클] CURSOR

심심이·2024년 3월 4일

oracle

목록 보기
32/40
PL/SQL 에서 SELECT 되어져 나오는 행의 개수가 2개 이상인 경우CURSOR 를 사용하여 나타낼 수도 있다. 
table 타입의 변수를 사용하는 것 보다 CURSOR 를 사용하는 것이 더 편하므로 
대부분 CURSOR 를 많이 사용한다.

커서 만들기

----- *** 명시적 CURSOR 만들기 *** -----
  ※ 형식
  1.단계 -- CURSOR 의 선언(정의)
     
    CURSOR 커서명
    IS
    SELECT 문;  

  2.단계 -- CURSOR 의 OPEN

    OPEN 커서명;

  3.단계 -- CURSOR 의 FETCH
           (FETCH 란? SELECT 되어진 결과물을 끄집어 내는 작업을 말한다)
    
    FETCH  커서명 INTO 변수;

  4.단계 -- CURSOR 의 CLOSE

    CLOSE 커서명;

프로시저 커서 단계별 설명


  create or replace procedure 프로시저 이름 ( 매개변수(타입선언)) 
  is
    CURSOR 커서명
    IS
    SELECT 문;  

begin
    OPEN 커서명;
    FETCH  커서명 
    INTO 변수;
    CLOSE 커서명;
    --닫히고 나서 if문 선언 등 작성 가능-- 
end 프로시저명;

커서의 속성변수



 ※ ==== 커서의 속성변수 ==== ※

 1. 커서명%ISOPEN   ==> 커서가 OPEN 되어진 상태인가를 체크하는 것.
                       만약에 커서가 OPEN 되어진 상태이라면 TRUE.

 2. 커서명%FOUND    ==> FETCH 된 레코드(행)이 있는지 체크하는 것.
                       만약에 FETCH 된 레코드(행)이 있으면 TRUE.

 3. 커서명%NOTFOUND ==> FETCH 된 레코드(행)이 없는지 체크하는 것.
                       만약에 FETCH 된 레코드(행)이 없으면 TRUE.
4. 커서명%ROWCOUNT ==> 현재까지 FETCH 된 레코드(행)의 갯수를 반환해줌.

실습

 
 
 create or replace procedure pcd_employees_deptid_cursor
 (p_department_id  IN  employees.department_id%type)
 is
    cursor cur_empinfo -- 1.단계 ==> CURSOR 의 선언(정의)
    is
        with E as
        (
          select department_id
               , employee_id
               , first_name || ' ' || last_name AS ENAME
               , to_char(hire_date, 'yyyy-mm-dd') AS HIREDATE
               , func_gender(jubun) AS GENDER
               , func_age(jubun) AS AGE
          from employees
          where department_id = p_department_id-- pk/unique가 아니기 때문에 복수 행수가 나온다. (유일한 값이 아니기 때문) -> 이걸 커서를 사용해서 나타냄
        )
        select E.department_id, D.department_name, E.employee_id, E.ename, E.hiredate, E.gender, E.age
        from departments D right join E
        on D.department_id = E.department_id;
        
        v_department_id    employees.department_id%type;
        v_department_name  departments.department_name%type;
        v_employee_id      employees.employee_id%type;
        v_ename            varchar2(30);
        v_hiredate         varchar2(10);
        v_gender           varchar2(6);
        v_age              number(3);
        
        v_fetch_count      number := 0; -- fetch_count 선언 
 begin
       -- 2.단계 ==> CURSOR 의 OPEN
       open cur_empinfo;
       
       -- 3.단계 ==> CURSOR 의 FETCH
       --           (FETCH 란? SELECT 되어진 결과물을 끄집어 내는 작업을 말한다)
       loop
           FETCH cur_empinfo -- cur_empinfo의 한 행을 끄집어내어서 변수에 담는다.
           INTO  v_department_id, v_department_name, v_employee_id, v_ename, v_hiredate, v_gender, v_age; 
           
           EXIT WHEN cur_empinfo%NOTFOUND;  -- 더 이상 FETCH 되어진 행이 없다면 반복문을 빠져나간다.!!  있다면 계속 반복한다. 
           
           v_fetch_count := cur_empinfo%ROWCOUNT; -- 현재까지 FETCH 된 레코드(행)의 갯수를 반환해줌.
           
           if (v_fetch_count = 1) then 
               dbms_output.put_line( lpad('-',60,'-') );
               dbms_output.put_line( '부서번호    부서명     사원번호     사원명    입사일자   성별   나이' );
               dbms_output.put_line( lpad('-',60,'-') );
           end if;
           
           dbms_output.put_line(v_department_id || ' ' || 
                                v_department_name || ' ' ||
                                v_employee_id || ' ' ||
                                v_ename || ' ' || 
                                v_hiredate || ' ' ||
                                v_gender || ' ' ||
                                v_age);
           -- fatch되어진 행들을 반복문을 돌면서 계속 출력한다. 
       end loop; 
       
       -- 4.단계 ==> CURSOR 의 CLOSE
       close cur_empinfo;
       
       if(v_fetch_count = 0) then -- v_fetch_count := cur_empinfo%ROWCOUNT; 이므로, 0일 경우 해당 행이 없다. 
          dbms_output.put_line('>> 부서번호 ' || p_department_id || '은 존재하지 않습니다. <<' ); 
       else
          dbms_output.put_line(' ');
          dbms_output.put_line('>> 조회된 행의 개수 : ' || v_fetch_count || '개 <<');
       end if;
       
 end pcd_employees_deptid_cursor;
 -- Procedure PCD_EMPLOYEES_DEPTID_CURSOR이(가) 컴파일되었습니다.
 
 exec pcd_employees_deptid_cursor(10);
 -- PL/SQL 프로시저가 성공적으로 완료되었습니다.
/*
    ------------------------------------------------------------
    부서번호    부서명     사원번호     사원명    입사일자   성별   나이
    ------------------------------------------------------------
    10 Administration 200 Jennifer Whalen 2003-09-17 여 45
     
    >> 조회된 행의 개수 : 1개 <<
*/
 
 exec pcd_employees_deptid_cursor(30);
 -- PL/SQL 프로시저가 성공적으로 완료되었습니다.
 /*
    ------------------------------------------------------------
    부서번호    부서명     사원번호     사원명    입사일자   성별   나이
    ------------------------------------------------------------
    30 Purchasing 114 Den Raphaely 2002-12-07 여 56
    30 Purchasing 115 Alexander Khoo 2003-05-18 남 62
    30 Purchasing 116 Shelli Baida 2005-12-24 남 61
    30 Purchasing 117 Sigal Tobias 2005-07-24 여 62
    30 Purchasing 118 Guy Himuro 2006-11-15 남 45
    30 Purchasing 119 Karen Colmenares 2007-08-10 남 44
     
    >> 조회된 행의 개수 : 6개 <<
 */
 
 exec pcd_employees_deptid_cursor(8888);
 -- PL/SQL 프로시저가 성공적으로 완료되었습니다.
 -- >> 부서번호 8888은 존재하지 않습니다. <<
 
 
 

커서 for문은 이쪽에 작성해두었습니다
https://velog.io/@nime0110/%EC%98%A4%EB%9D%BC%ED%81%B4-for%EB%AC%B8

profile
개발하는 심심이

0개의 댓글