/* 커서(cursor) : 쿼리문에 의해서 반환되는 결과값들을 저장하는 메모리 공간
Fetch : 커서에서 원하는 결과값을 추출하는 것
- 커서의 종류
- 명시적(Explicit) 커서 : 사용자가 선언 후 사용하는 SQL 커서,
주로 여러개의 행을 처리하고자 할 경우 사용
- 묵시적(Implicit) 커서 : 오라클에서 자동으로 선언해주는 SQL 커서,
사용자는 생성 유무를 알 수 없다. 한 행만 처리 가능.
- 커서의 속성
%Found - 할당할 레코드가 있는 경우 true 반환
%isOpen - 커서가 오픈 상태일 경우 true 반환
%NotFound - 할당할 레코드가 없는 경우 true 반환
%RowCount - 카운터 역할. 오픈 됐을 경우 0, 패치 발생할 때마다 1씩 증가
- 커서의 처리단계(명시적 커서)
1. 명시적 커서 선언 -> Cursor 커서 이름
2. 명시적 커서 오픈 -> Open 커서이름
3. 커서에서 데이터 추출 -> Fetch 커서이름
4. 커서 종료 -> Close 커서이름
*/
set serveroutput on;
declare
emp_id number(4); -- 변수 선언
emp_name varchar2(10);
emp_salary number(10);
Cursor cu1 is
select employee_id, last_name, salary
from employees
where department_id = 50;
begin
open cu1;
dbms_output.put_line('사번 이름 급여');
loop
fetch cu1 into emp_id, emp_name, emp_salary; -- 커서에서 값을 꺼내오는(추출) 것
exit when cu1%notFound;
dbms_output.put_line(emp_id||' '||emp_name||' '||emp_salary);
end loop;
close cu1; -- 커서 닫기
end;
/
/* 커서와 반복문(For문)
- 사용 형식
For 레코드 네임 IN 커서 이름 LOOP
명시적 커서의 OPEN, FETCH 가 자동으로 수행
실행 문장들
END LOOP; -- 루프문을 빠져나갈 때 자동적으로 커서가 종료됨
*/
declare
cursor emp_cur is
select employee_id, last_name
from employees;
begin
for emp_rec in emp_cur loop
dbms_output.put_line(emp_rec.employee_id||' '||emp_rec.last_name);
end loop;
end;
/
declare
emp employees%rowType;
cursor cur1 is
select employee_id, last_name, salary
from employees;
begin
for emp in cur1 loop
exit when cur1%notfound;
dbms_output.put_line(emp.employee_id||' '||emp.last_name||' '||emp.salary);
end loop;
end;
/
declare
begin
for emp in(select employee_id, last_name, salary
from employees) -- 커서명 대신 바로 쿼리를 써준다(묵시적 커서)
loop
dbms_output.put_line(emp.employee_id||' '||emp.last_name||' '||emp.salary);
end loop;
end;
/
/* 묵시적 커서 사용 예 : 속성 사용시
SQL%notfound, SQL%rowcount, SQL%found, SQL%isopen 등의 형태로 사용
*/
declare
cnt1 number;
cnt2 number;
begin
select count(*) into cnt1
from employees
where department_id = 50;
cnt2 := sql%rowcount; -- 묵시적 커서의 경우 속성 사용시 커서이름 자리에 sql이 들어간다
-- fetch 할 때마다 1씩 값이 증가
dbms_output.put_line('cnt1의 값 : '||cnt1); -- count(*)의 값
dbms_output.put_line('cnt2의 값 : '||cnt2); -- count(*)의 값을 커서에 넘겨준 횟수(fetch 발생 횟수)
end;
/