ORACLE·plsql

[펌]Cursor

administrators 2009. 12. 23. 16:57

커서(Cursor)

개별적인 sql area의 이름

현재위치표시자

실행중에만 사용가능.실행이 끝나면 없어진다.

데이터베이스 테이블 - 공용
커서 - 개인적

 

리절트셋 - sql실행후의 결과셋

               한번에 하나의 행만읽을수 있다.(커서가 위치한 행)

               커서를 움직여 읽는다.

 

암시적 커서 - 오라클 자체에서 사용하는 커서

 

명시적 커서 - 사용자가 직접만든 커서

 

사용순서 :

     declare(선언) - open(결과 가져오기) - fetch(현재커서내용가져오기) - close(커서제거)

 

예)while문

 

set serveroutput on

create or replace procedure p_emp_info
(p_dept_id s_eno,dept_id%type)
is
  --커서 선언
  cursor c_emp_sal is   --결과셋이 없으면 커서도 사용못한다
     select last_name, salary
   from e_emp
   where dept_id = p_dept_id;
  
  
  -- 변수 선언
  v_sal s_emp.salary%type;
  v_last_name s_emp.last_name%type;
 
begin
  --커서 생성(열기)
  open c_emp_sal;
 
  loop
    --한개의 행을 가져오기
 fetch c_emp_sal into v_last_name, v_sal;--하나하나의 행은 레코드에 가능하지만 전체가 들어가지못한다?
 if c_emp_sal%notfound then-- 커서가 끝에 다달으면 속성이 true가된다
   exit;
 end if
 dbms_output.put_line( v_last_name||' '||v_sal);
  end loop;
  --커서 제거(닫기)
  close c_emp_sal;
 
end;
/

 

exec p_emp_info(31); -- 프로시저 실행

show errors; -- 에러출력

 

예)for문 - for 다음에오는 변수는 레코드타입이다.

 

set serveroutput on

create or replace procedure p_emp_info
(p_dept_id s_eno,dept_id%type)
is
  --커서 선언
  cursor c_emp_sal is   --결과셋이 없으면 커서도 사용못한다
     select last_name, salary
   from e_emp
   where dept_id = p_dept_id;
  
 
begin
  --커서 생성(열기)
  --자동 생성, 자동 페취, 자동 제거
 
  for emp_rec in c_emp_sal loop
 
     dbms_output.put_line( emp_rec.last_name||' '||emp_rec.salary);
 
  end loop;

end;
/

 

exec p_emp_info(31); -- 프로시저 실행

show errors;

 

기본 Cursor는 읽을수만 있지 수정이 불가. for update를 제작시 뒤에 명시하면 수정이 가능.

Current Of를 사용하여 현재 커서의 위치에 있는 해당 컬럼을 바꾸라는 명령을 할 수 있다.

 

커서생성시 커서에 받아들일 수 있는 값을 지정할 수 있다.

for문에 커서명을 넣을 때 괄호를 사용하여 입력하여 사용할 수 있다.

예)

set serveroutput on

declare
  cursor c_dept is
     select * from s_dept;
  cursor c_emp_sal(p_dept_id s_emp.dept_id%type) is
     select last_name, salary
   from s_emp
   where dept_id=p_dept_id;
begin

  for dept in c_dept loop
     dbms_output.put_line('=========================');
   dbms_output.put_line(dept.id||'::'||dept.name);
  
   for emp_record in c_emp_sal(dept.id) loop
      dbms_output.put_line(emp_record.last_name||' '||emp_record.salary);
    end loop;
  
  end loop;

end;
/

 

 

[출처] Cursor|작성자 솔닷줴이

http://blog.naver.com/pureb612b/10038509345