2012-10-07

DBMS/오라클]오라클_커서_사용법


원본 출처 :: http://netme.kr/bbs/board.php?bo_table=sub_2011&wr_id=23


1.  커서의  정의

커서란  SQL  Plus에서  사용자가  실행한  SQL문의  단위를  의미합니다.
오라클렝서  수행한  모든  쿼리문은  커서  단위로  처리합니다.

PL/SQL의  SQL문처럼  하나의  결과를  리턴하는  경우  커서  없이도  SQL문의  실행결과가 
암시적으로  커서에  저장되므로  이를  암시적  커서라고  합니다.

SQL문을  수행한  후에  결과로  얻어지는  행이  여러  개일  경우에는  암시적인  커서에  정보를 
저장할  수  없기에  에러가  발생합니다.  이럴  경우에는  반드시  명시적인  커서를  사용해야  합니다.

명시적인  커서는  PL/SQL의  레코드(RECORD)와  PL/SQL의  테이블(TABLE)을  결합한  것으로서
프로그램  언어의  구조체  배열과  유사합니다.



[커서의  사용]

1)  커서를  선언한다.
CURSOR  cur_name

2)  커서를  오픈한다.
OPEN  cur_name

3)  커서에  조회한  결과를  인출해  지정한다.
FECTCH  cur_name  ...

4)  커서를  닫는다
CLOSE  cur_name






2.  20번  부서에  근무하는  사원의  정보를  출력하는  예제


ed  cur01


SET  SERVEROUTPUT  ON
declare
   vempno   NUMBER(4);
   vename   VARCHAR2(20);
   vsal   NUMBER(7,  2);

   CURSOR   C1
   IS
   select  empno,  ename,  sal
   from  emp
   where  deptno=20;

begin
   OPEN  C1;

   dbms_output.put_line('empno   ename   sal');

   LOOP
      FETCH  C1  INTO  vempno,  vename,  vsal;
      EXIT  WHEN  C1%NOTFOUND;

      dbms_output.put_line(to_char(vempno)||'   '||vename||'   '||to_char(vsal));
   END  LOOP;


end;
/



저장하고  실행합니다.

@cur01
empno   ename   sal
7369   SMITH   800
...
...
...
...
...

PL/SQL  procedure  successfully  completed.





3.  OPEN-FETCH-CLOSE가  없이  커서  처리

ed  cur02


SET  SERVEROUTPUT  ON
declare
   vemp   emp%ROWTYPE;

   CURSOR   C1
   IS
   select  empno,  ename,  sal
   from  emp
   where  deptno=20;

begin
   dbms_output.put_line('empno   ename   sal');

   FOR   vemp   IN   C1   LOOP
      EXIT  WHEN  C1%NOTFOUND;

      dbms_output.put_line(to_char(vemp.empno)||'   '||vemp.ename||'   '||to_char(vemp.sal));
   END  LOOP;

end;
/


정장하고  실행합니다.

@cur02
empno   ename   sal
7369   SMITH   800
...
...
...
...
...

PL/SQL  procedure  successfully  completed.



4.  커서의  상태

%NOTFOUND   커서  영역의  자료가  모두  FETCH  됬는가를  알려줌
%FOUND      커서  영역에  FETCH가  되지  않은  자료가  있는가를  알려줌
%ISOPEN      커서가  OPEN된  상태인가를  알려줌
%ROWCOUNT   FETCH된  RECORD가  몇  개  있는지  알려줌

cur02  예제를  수정합니다.

ed  cur02

SET  SERVEROUTPUT  ON
declare
   vemp   emp%ROWTYPE;

   CURSOR   C1
   IS
   select  empno,  ename,  sal
   from  emp
   where  deptno=20;

begin
   dbms_output.put_line('empno   ename   sal   record  count');

   FOR   vemp   IN   C1   LOOP
      EXIT  WHEN  C1%NOTFOUND;

      dbms_output.put_line(to_char(vemp.empno)||'   '||vemp.ename||'   '||to_char(vemp.sal)||'   '||C1%ROWCOUNT);
   END  LOOP;

end;
/


저장하고  실행합니다.

@cur02

결과는  record  count  추가되었습니다.




5.  커서를  활용한  실용  예제
1)  급여  총합을  구하는  예제
ed  cur03

SET  SERVEROUTPUT  ON
declare
   tot   NUMBER  :=  0;

   CURSOR   emp_cursor
   IS
   select  ename,  sal
   from  emp;

begin
   dbms_output.put_line('name   sal');
   dbms_output.put_line('------------------------------------------');

   FOR  cur_var  IN  emp_cursor  LOOP
      tot  :=  tot  +  cur_var.sal;
      dbms_output.put_line(cur_var.ename);
      dbms_output.put_line('-   '||cur_var.sal);
   END  LOOP;
  
   dbms_output.put_line('------------------------------------------');
   dbms_output.put_line('-   '||tot);
end;
/


저장하고  실행합니다

@cur03




2)  사원별  급여  현황을  그래포로  표현
ed  cur04

SET  SERVEROUTPUT  ON
declare
   CURSOR   emp_cursor
   IS
   select  ename,  sal
   from  emp
   order  by  sal  desc;

   star   varchar2(100);
   cnt   number  :=  0;

begin
   dbms_output.put_line('   sal  of  emp');
   dbms_output.put_line('------------------------------------------');

   FOR  cur_var  IN  emp_cursor  LOOP
      star  :=  NULL;
      cnt  :=  round(cur_var.sal/100,  0);

      for  i  in  1..  cnt  loop
         star  :=  star||'*';
      end  loop;

   dbms_output.put_line(cur_var.ename);
   dbms_output.put_line('-   '||star||'('||cur_var.sal||')');
   END  LOOP;
end;
/


저장하고  실행합니다

@cur04

댓글 1개: