Oracle
[days14] Cursor (커서)
다연
2020. 11. 17. 21:24
반응형
1. PL/SQL 블럭 내에서 실행되는 select 문을 의미한다.
2. select 문을 처리한 여러개의 행을 가지고 있는 결과를 담고 있는 메모리 영역을 가리키는 일종의 포인터가 커서이다.
3. 커서의 종류
ㄱ. 묵시적(implicit) - 한 번 실행에 하나의 결과를 반환하는 SQL문을 의미 함
ㄴ. 명시적(explicit) - 여러 개의 행이 반환되는 SQL문을 실행하는 경우
1) 커서 선언
2) 커서 open
3) 반복문을 사용해서 fetch (가져오기)
4) 커서 close
예) empno를 입력해 3명 가져오기 (3명 이하면 전부 가져오기)
declare
vempno emp.empno%type;
vename emp.ename%type;
vsal emp.sal%type;
--1. 커서 선언
cursor emp_cursor is ( --커서 자체가 select를 의미
select empno, ename, sal
from emp
where deptno = :pdeptno
);
begin
--2. 커서 오픈 ->실질적으로 위 셀렉트 문을 실행하겠다
open emp_cursor;
-- select empno, ename, sal
-- from emp
-- where deptno = :pdeptno; 이 세줄을 커서 안에다 갖다붙힘
--3. fetch
loop
fetch emp_cursor into vempno, vename, vsal;
dbms_output.put_line(vempno||','||vename||','||vsal);
exit when emp_cursor%notfound or emp_cursor%rowcount>=3; --%notfound : 더이상 읽을 행이 없음을 알 수 있음
--끝을 만나도 빠져나오고 3개만 출력해도 빠져나오기
end loop;
--4. 커서 close
close emp_cursor;
--exception
end;
만일 deptno에 30을 입력한다면
for문 사용하여 위의 쿼리 수정
declare
vrow emp%rowtype;
cursor emp_cursor is select empno, ename, sal from emp;
begin
--open emp_cursor;
--06511. 00000 - "PL/SQL: cursor already open"
--for문 사용하니까 open close 필요 없이 cursor 사용 가능하다
--형식2 CURSOR FOR LOOP
--for 레코드(행)명 in 커서명
--loop
--end loop
for vrow in emp_cursor
loop
dbms_output.put_line(vrow.empno||','||vrow.ename||','||vrow.sal);
end loop;
-- if emp_cursor%isopen then
-- close emp_cursor;
--exception
end;
위쿼리 복붙 암시적 커서
declare
--vrow emp%rowtype; 얘도 선언 필요 없다 알아서 row 세줌
--cursor emp_cursor is select empno, ename, sal from emp;
--커서 선언도 지우고
begin
for vrow in (select empno, ename, sal from emp) --여기에 커서 내용 복붙해도 된다 : 암시적 커서
loop
dbms_output.put_line(vrow.empno||','||vrow.ename||','||vrow.sal);
end loop;
end;
다시 복붙 - record형 변수
declare
type emptype is record --emptype 이름으로
(
empno emp.empno%type
,ename emp.ename%type
,sal emp.sal%type
); --타입 선언
vrow emptype; --emptype으로 vrow 선언
cursor emp_cursor is select empno, ename, sal from emp;
begin
open emp_cursor;
loop
fetch emp_cursor into vrow;
dbms_output.put_line(vrow.empno||','||vrow.ename||','||vrow.sal);
exit when emp_cursor%notfound;
end loop;
close emp_cursor;
end;
반응형