학원 45일차 - Oracle
ex29_plsql.sql
PL/SQL
- select -> 결과셋 -> PL/SQL 변수
- select into절 사용
- 결과셋의 레코드가 1개일때만 사용 가능(★★★)
- 결과셋의 컬럼은 1개 이상 ~
declare
변수선언;
begin
select 컬럼 into 변수 from 테이블;
end;
- cursor 사용
- 결과셋의 레코드가 0개 이상일때 사용 가능(N개)
- 결과셋의 컬럼은 1개 이상 ~
- 일반적으로 결과셋의 레코드가 2개 이상일 때 권장
- 자바의 Iterator 구조와 유사(데이터의 집합을 탐색(접근)하는 방식-차례대로 하나씩 순차적으로 접근)
declare
커서선언;
begin
커서열기;
loop
레코드 접근 -> 커서 사용
end loop;
커서닫기;
end;
set serveroutput on;
declare
vname tblInsa.name%type;
begin
-- select name into vname from tblInsa where num = 1000; -- 데이터가 0개면 에러(into절은 무조건 1개일때 사용)
-- select name into vname from tblInsa -- 레코드의 갯수가 여러개면 에러
select name into vname from tblInsa where num = 1001; -- PK
dbms_output.put_line(vname); -- 홍길동
end;
-- 여러 레코드를 가져오는 방법 : cursor사용
declare
vname tblInsa.name%type;
-- 커서 선언
-- 자료형 변수명 is select 컬럼 from 테이블명;
-- 1. select하고 싶은 문장을 cursor로 만든다.
cursor vcursor is select name from tblInsa; -- 결과셋 참조 객체
begin
-- 2. 커서 열기 : 커서가 가지고 있는 select문이 실행된다. > 결과셋 > 커서가 참조
open vcursor;
-- 커서 조작 -> 결과셋 탐색
-- 3. loop: 결과셋의 레코드들을 탐색 루프(한줄씩 접근)
loop
-- 커서를 전진한다. + 커서가 가르키는 레코드의 컬럼 접근(읽기)
-- 4. vcursor가 읽어온 컬럼리스트의 값을 vname변수에 넣는다.(루프반복)
fetch vcursor into vname; -- select name into vname과 유사(일회성)
-- 5. 탈출 -> 더이상 읽어올 레코드가 없을 때
exit when vcursor%notfound; -- 커서 프로퍼티, notfound : 더이상 읽어올 레코드가 없으면 true를 반환
-- 6. 사용
dbms_output.put_line(vname);
end loop;
-- 커서 닫기
close vcursor;
end;
select * from tblCounty;
declare
cursor vcursor
is select name, capital, population from tblCountry order by name asc;
vname tblCountry.name%type;
vcapital tblCountry.capital%type;
vpopulation tblCountry.population%type;
begin
open vcursor;
loop
-- select name, capital, population into vname, vcapital, vpopulation
fetch vcursor into vname, vcapital, vpopulation;
exit when vcursor%notfound;
dbms_output.put_line(vname || '-' || vcapital || '-' || vpopulation);
end loop;
close vcursor;
end;
select * from tblBonus;
-- 개발부 직원 -> 모두 보너스 지급
declare
cursor vcursor is select num, basicpay from tblInsa where buseo = '개발부';
vnum tblInsa.num%type;
vbasicpay tblInsa.basicpay%type;
begin
open vcursor;
loop
fetch vcursor into vnum, vbasicpay;
exit when vcursor%notfound;
-- 여기서부터 업무에 따라 고민..
insert into tblBonus(seq, pnum, bonus, regdate)
values (seqBonus.nextVal, vnum, round(vbasicpay * 0.7), default);
end loop;
close vcursor;
end;
-- 기본버전
-- tblInsa.개발부 직원 + 모든 컬럼
declare
cursor vcursor is select * from tblInsa where buseo = '개발부';
vrow tblInsa%rowtype; -- 레코드 참조 변수 (컬럼 10개짜리)
begin
open vcursor;
loop
fetch vcursor into vrow; -- 컬럼 10개 -> 변수 10개 복사
exit when vcursor%notfound;
dbms_output.put_line(vrow.name);
dbms_output.put_line(vrow.buseo);
dbms_output.put_line('---');
end loop;
close vcursor;
end;
-- 간단버전
declare
cursor vcursor is select * from tblInsa where buseo = '개발부'; -- 그대로
-- vrow tblInsa%rowtype; -- 생략 -> 아래에서 만든다.
begin
-- open vcursor;
for vrow in vcursor loop
-- fetch vcursor into vrow;
-- exit when vcursor%notfound;
dbms_output.put_line(vrow.name);
dbms_output.put_line(vrow.buseo);
dbms_output.put_line('---');
end loop;
-- close vcursor;
end;
declare
cursor vcursor is select * from tblInsa where buseo = '개발부';
begin
for vrow in vcursor loop -- for loop로 커서탐색, vrow + loop + fetch ++ exit when
dbms_output.put_line(vrow.name);
dbms_output.put_line(vrow.buseo);
dbms_output.put_line('---');
end loop;
end;
create view vwDev
as
select * from tblInsa where buseo = '개발부';
select * from vwDev;
select * from (select * from tblInsa where buseo = '개발부'); -- 인라인뷰
--------------------------------------------------------------------
-- 더 간단버전(권장x)
-- 인라인터서 -> 가독성이 낮음
-- 단순한 쿼리에 한해서 사용
begin
for vrow in (select * from tblInsa where buseo = '개발부') loop
dbms_output.put_line(vrow.name);
dbms_output.put_line(vrow.buseo);
dbms_output.put_line('---');
end loop;
end;
프로시저
- PL/SQL 블럭(declare, begin, exception, end로 구성)
- 익명 프로시저
- 일회용(DB에 저장이 안됨, HDD에 *.sql로 저장)
- 객체x
- 속도 느림
- 테스트용, 임시 개발용
- 실명 프로시저
- 저장용(DB에 저장이 됨)
- 객체O
- 재사용이 가능, 타 유저에게 공유 가능
- 속도 빠름
- 업무용
실명 프로시저의 종류 (저장 프로시저라는 말을 더 많이 씀(Stored Procedure))
- 저장 프로시저(Stored Procedure)
- 매개변수 구성 or 반환값 구성 -> 자유
- 저장 함수 (Stored Function)
- 매개변수 필수, 반환값 필수 -> 고정
익명 프로시저 vs 저장 프로시저
익명프로시저 선언
[declare
변수 선언;
커서 선언;]
begin
구현부;
[exception
예외처리;]
end;
저장프로시저 선언
create [or replace] procedure 프로시저명
is(as)
[변수 선언;
커서 선언;]
begin
구현부;
[exception
예외처리;]
end [프로시저명];
-- 익명
declare
vnum number;
begin
vnum := 100;
dbms_output.put_line(vnum);
end;
-- 실명
-- Procedure PROCTEST이(가) 컴파일되었습니다. > 프로시저가 만들어짐. 보려면 호출을 해야한다.
create or replace procedure procTest
is
vnum number;
begin
vnum := 100;
dbms_output.put_line(vnum);
end procTest;
저장 프로시저를 호출하는 방법
- 스크립트 환경에서 호출하기(ANSI-SQL 환경에서)
- PL/SQL 블럭에서 호출하기
-- 2. PL/SQL 블럭에서 호출하기
-- PL/SQL 환경을 만들어줘야지만 호출 가능
begin
procTest; -- 인자값이 없는 메소드 호출, ()소괄호사용x
end;
-- ANSI-SQL환경이기때문에 실행 x
-- ANSI-SQL에서는 create, insert, delete, alter, select.. 등만 사용가능
-- procTest;
-- 1. 스크립트 환경에서 호출하기(ANSI-SQL 환경에서 호출)
execute procTest;
exec procTest;
call procTest(); -- call 사용시 () 필수!
Author And Source
이 문제에 관하여(학원 45일차 - Oracle), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@hi-dae-in/학원-45일차-Oracle저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)