// ANSI-SQL
- 비절차 지향 언어
- 순서가 없고 문장 간의 행동이 서로 독립적이다.
- 문장 단위 구조
// PL/SQL
- Oracle's Procedural Language Extension to SQL
- ANSI-SQL에 절차 지향 언어의 기능을 추가한 SQL
- ANSI-SQL + 프로그래밍 언어의 기능(변수, 자료형, 제어문, 메서드 ...)
- ANSI-SQL의 환경과 거의 동일하게 구현
// 프로시저, Procedure
- 메서드, 함수 ...
- 순서가 있는 명령어(ANSI-SQL + PL/SQL)의 집합
- 장점
1. 단순화(모듈화)
2. 팀작업 원활
3. 저장 객체 > 공유 원활
4. 속도 향상★
- PL/SQL 프로시저 블럭 구조 > 4개의 키워드(블럭)으로 구성
a. declare
- 선언부
- 프로시저 내에서 사용할 변수, 객체 등을 선언하는 영역
- 생략 가능
b. begin
- 실행부, 구현부
- begin ~ end 한 쌍
- 구현부의 시작
- 생략 불가능
- 핵심 파트
- 구현 코드 : ANSI-SQL + PL/SQL
c. exception
- 예외 처리부
- 자바에서의 catch 역할 (begin~end가 try 역할까지!)
- 예외 처리 코드 작성
- 생략 가능
d. end
- begin ~ end 한 쌍
- 구현부의 끝 > begin 블럭의 종료 역할
- 생략 불가능
1. 익명 프로시저
- 일회용 코드 > 재사용 X
declare
변수 선언 | 객체 선언
begin
구현할 코드(SQL)
exception
예외처리 코드
end;
begin
구현할 코드(SQL)
end;
- 값 출력
dbms_output.put_line(값)
-- ≒ System.out.println()
set serveroutput on | set serverout on : dbms_output.put_line(값)의 결과가 보이게 설정
set serveroutput off | set serverout off : dbms_output.put_line(값)의 결과가 안 보이게 설정
-- 일회성 > 접속할 때마다 실행해줘야 함.
2. 실명 프로시저
- 저장 프로시저(Stored Procedure)
- 저장(데이터베이스) > DB Object
- 재사용 가능
- 계정 간 공유 가능
- ★★★★★매개변수는 길이와 not null 표현이 불가능하다.
1. 저장 프로시저, Stored Procedure
- 매개 변수 구성 / 반환값 구성 > 자유
--선언
create [or replace] procedure 프로시저명
is(as)
[변수 선언;
커서 선언;]
begin
구현부;
[exception
처리부;]
end 프로시저명;
--호출
begin
프로시저명;
end;
2. 저장 함수, Stored Function
- 저장 프로시저와 동일하지만 프로시저와 조금 다른 상황에서 사용★★★
- 매개변수 필수 / 반환값 필수 > 고정
- out 파라미터 사용 X > return 문 사용 O
- in 파라미터는 사용!
- ANSI-SQL에서도 사용할 수 있다. > 이 용도로 저장 함수 사용
create or replace function 프로시저명 (
매개변수
) return 반환타입
is
begin
return 반환값;
end 프로시저명;
declare
변수 선언;
begin
변수명 := 프로시저명(매개변수);
dbms_output.put_line(변수명);
end;
- 저장 프로시저
create or replace procedure procTest(
width number,
height number
)
is
vnum number;
vresult number;
begin
vnum := width * height;
dbms_output.put_line(vnum);
end procTest;
begin
procTest(10,20);
end;
create or replace procedure procTest(
pname varchar2
)
is
begin
dbms_output.put_line('안녕하세요. ' || pname || '님');
end procTest;
begin
procTest('홍길동');
end;
- 저장 함수
create or replace function fnSum (
pnum1 number,
pnum2 number
) return number
is
begin
return pnum1 + pnum2;
end fnSum;
declare
vresult number;
begin
-- 함수 return > 개수 딱 1개 <-> 프로시저 out > 개수 1개 이상
vresult := fnSum(10, 20);
dbms_output.put_line(vresult);
end;
create or replace function fnSum (
pnum1 number,
pnum2 number
) return number
is
begin
return pnum1 + pnum2;
end fnSum;
select
height, weight,
fnSum(height, weight) as sum
from tblComedian;
create or replace function fnGender(
pssn varchar2
) return varchar2
is
begin
return case substr(pssn, 8, 1)
when '1' then '남자'
when '2' then '여자'
end;
end fnGender;
select
name, buseo, jikwi, fnGender(ssn) as gender
from tblInsa;
// 자료형
- ANSI-SQL과 거의 동일
// 변수 선언
~ 변수명 자료형 [not null] [default 값];
- 일반적인 데이터를 저장하는 용도
- 주로 질의(select)의 결과값을 저장하는 용도로 사용됨.
- 초기화를 하지 않더라도 null 상태로 사용 가능 (but 그렇게 사용할 일이 딱히 x)
// 연산자
- ANSI-SQL과 거의 동일하지만, 대입 연산자의 표기법이 다름!
1. ANSI-SQL
~ update table set column = 값;
2. PL/SQL
~ 변수 := 값;
declare
num number;
name varchar2(30);
today date;
begin
num := 10;
dbms_output.put_line(num);
name := '홍길동';
dbms_output.put_line(name);
today := sysdate;
dbms_output.put_line(today);
end;
declare
num1 number;
num2 number;
num3 number := 30;
num4 number default 40;
num5 number not null := 50;
num6 number not null default 0;
begin
num1 := 10;
dbms_output.put_line(num1);
dbms_output.put_line('---');
dbms_output.put_line(num2); --null
dbms_output.put_line('---');
dbms_output.put_line(num3);
dbms_output.put_line(num4);
num4 := 400;
dbms_output.put_line(num4);
dbms_output.put_line(num5);
end;
// 타입 참조
- 변수를 선언할 때 같이 사용
1. %type
- 사용하는 테이블의 특정 컬럼의 스키마를 알아내서 변수에 적용
- 복사되는 정보
a. 자료형
b. 길이
변수 테이블명.컬럼%type;
2. %rowtype
- 레코드 전체 참조(모든 컬럼 참조)
- 와일드 카드의 성질
- 테이블 구조 순서대로 컬럼을 가져온다.
변수 테이블명%rowtype;
- %type
declare
vname tblInsa.name%type; -- vname varchar2(20);
vbuseo tblInsa.buseo%type;
vjikwi tblInsa.jikwi%type;
begin
select name, buseo, jikwi into vname, vbuseo, vjikwi from tblInsa where num = 1002;
dbms_output.put_line(vname);
dbms_output.put_line(vbuseo);
dbms_output.put_line(vjikwi);
end;
--1. ANSI-SQL
insert into tblBonus values(seqBonus.nextVal,
(select num from tblInsa where buseo = '총무부' and jikwi = '부장'),
(select basicpay from tblInsa where buseo = '총무부' and jikwi = '부장') * 1.5);
--2. PL/SQL
declare
vnum tblInsa.num%type;
vbasicpay tblInsa.basicpay%type;
begin
select num, basicpay into vnum, vbasicpay from tblInsa
where buseo = '총무부' and jikwi = '부장';
insert into tblBonus values (seqBonus.nextVal, vnum, vbasicpay * 1.5);
end;
select * from tblBonus;
- %rowtype
declare
vrow tblInsa%rowtype; --테이블 구조 순서대로 컬럼을 가져옴.
begin
select * -- num, name, ssn, ibsadate, city, tel, buseo, jikwi, basicpay, sudang
into vrow
from tblInsa where name = '이순신';
dbms_output.put_line(vrow.name);
dbms_output.put_line(vrow.num);
dbms_output.put_line(vrow.ssn);
dbms_output.put_line(vrow.ibsadate);
dbms_output.put_line(vrow.city);
dbms_output.put_line(vrow.tel);
dbms_output.put_line(vrow.buseo);
dbms_output.put_line(vrow.jikwi);
dbms_output.put_line(vrow.basicpay);
dbms_output.put_line(vrow.sudang);
end;
// 제어문
1. 조건문
2. 반복문
// 조건문
a. if elsif else
if 조건식 then
실행문;
elsif 조건식 then
실행문;
else
실행문;
end if;
b. case(≒if)
case
when 조건식 then 실행문1;
else 실행문2;
end case;
~ case(≒switch)
case 변수
when 조건 then 실행문1;
else 실행문2;
end case;
c. if elsif else
declare
vnum number := 10;
begin
if vnum > 0 then
dbms_output.put_line('양수');
end if;
end;
declare
vnum number := -10;
begin
if vnum > 0 then
dbms_output.put_line('양수');
else
dbms_output.put_line('양수 아님');
end if;
end;
declare
vnum number := 0;
begin
if vnum > 0 then
dbms_output.put_line('양수');
elsif vnum < 0 then
dbms_output.put_line('음수');
else
dbms_output.put_line('0');
-- null > 빈 구문 만들 때 사용
end if;
end;
declare
vnum tblInsa.num%type;
vbasicpay tblInsa.basicpay%type;
vjikwi tblInsa.jikwi%type;
vbonus number;
begin
--1.
select num, basicpay, jikwi into vnum, vbasicpay, vjikwi from tblInsa where name = '이순신';
--2.
if vjikwi = '부장' or vjikwi = '과장' then
vbonus := vbasicpay * 1.5;
elsif vjikwi in ('사원', '대리') then
vbonus := vbasicpay * 2;
end if;
--3.
insert into tblBonus values (seqBonus.nextVal, vnum, vbonus);
end;
select
b.*,
(select name from tblInsa where num = b.num) as name,
(select jikwi from tblInsa where num = b.num) as jikwi,
(select basicpay from tblInsa where num = b.num) as basicpay
from tblBonus b;
~ case(if)
declare
vcontinent tblCountry.continent%type;
vresult varchar2(30);
begin
select continent into vcontinent from tblCountry where name = '대한민국';
case
when vcontinent = 'AS' then vresult := '아시아';
when vcontinent = 'EU' then vresult := '유럽';
when vcontinent = 'AF' then vresult := '아프리카';
else vresult := '기타';
end case;
dbms_output.put_line(vresult);
end;
~ case(switch)
declare
vcontinent tblCountry.continent%type;
vresult varchar2(30);
begin
select continent into vcontinent from tblCountry where name = '대한민국';
case vcontinent
when 'AS' then vresult := '아시아';
when 'EU' then vresult := '유럽';
when 'AF' then vresult := '아프리카';
else vresult := '기타';
end case;
dbms_output.put_line(vresult);
end;
// 반복문
a. loop
- 단순 반복(무한 반복)
loop
실행문;
[exit when 조건식;] --조건 만족시 loop 탈출
end loop;
b. for loop
- 횟수 반복 (≒자바 for)
- loop 기반
for i in startIndex..endIndex loop
실행문;
end loop;
c. while loop
- 조건 반복 (≒자바 while)
- loop 기반
while 조건식 loop
실행문;
end loop;
- loop
insert into tblLoop values(seqLoop.nextVal, '데이터1');
insert into tblLoop values(seqLoop.nextVal, '데이터2');
insert into tblLoop values(seqLoop.nextVal, '데이터3');
declare
vnum number := 4;
begin
loop
insert into tblLoop values(seqLoop.nextVal, '데이터' || vnum);
vnum := vnum + 1;
exit when vnum > 1000;
end loop;
end;
select * from tblLoop;
- for loop
begin
for dan in 2..9 loop
for num in 1..9 loop
insert into tblGugudan (dan, num, result) values (dan, num, dan * num);
end loop;
end loop;
end;
select * from tblGugudan;
- while loop
declare
vnum number := 1;
begin
while vnum <= 10 loop
dbms_output.put_line(vnum);
vnum := vnum + 1;
end loop;
end;
// select 결과셋 저장
- select 결과셋 > PL/SQL 변수에 대입
1. select into
2. cursor + loop
// select into 절
~ select 컬럼 into 변수
- PL/SQL의 변수에 ANSI-SQL의 결과값을 저장하는 구문
- ★★★★★★★select의 결과는 반드시 PL/SQL에 넣어야 한다.
- ★★★★★★★PL/SQL 블럭 안에는 ANSI-SQL의 select문을 사용할 수 없다.
- ★★★★★★★PL/SQL 블럭 안에서는 select문을 제외한 ANSI-SQL은 그대로 사용 가능하다.(insert, update, delete)
- 주의점
1. 컬럼의 개수와 변수의 개수가 동일해야 한다.
2. 컬럼의 순서와 변수의 순서가 일치해야 한다.
3. 컬럼과 변수의 자료형이 일치해야 한다.
- null 처리 함수(null value 함수)
1. nvl(컬럼, 대체값)
- 컬럼의 값이 null이면 대체값 반환
2. nvl2(컬럼, 값A, 값B)
- 컬럼의 값이 null이 아니면 값A 반환, null이면 값B 반환
declare
vname varchar2(30);
buseo varchar2(30);
begin
select name into vname from tblInsa where num = 1001;
dbms_output.put_line(vname);
-- 컬럼 변수
select buseo into buseo from tblInsa where num = 1001;
dbms_output.put_line(buseo);
-- 변수
end;
declare
vnum number;
vname varchar2(15);
begin
--select의 결과는 반드시 PL/SQL에 넣어야 한다.
select num into vnum from tblInsa where buseo = '개발부' and jikwi = '부장';
select name into vname from tblInsa where buseo = '개발부' and jikwi = '부장';
insert into tblTeam values(vnum, vname, '개발부', '부장');
end;
select * from tblTeam;
declare
vname varchar2(15);
vbuseo varchar2(15);
vjikwi varchar2(15);
begin
select name, buseo, jikwi into vname, vbuseo, vjikwi from tblInsa where num = 1001;
dbms_output.put_line(vname);
dbms_output.put_line(vbuseo);
dbms_output.put_line(vjikwi);
end;
- null 처리 함수
select name, nvl(tel, '대체값') from tblInsa;
select name, nvl2(tel, '값A', '값B') from tblInsa;
// cursor + loop★★★★★★★★★
- 결과셋의 레코드가 n개일 때 사용한다.
a. cursor + loop
declare
변수 선언;
cursor 커서명 is select문;
begin
open 커서명; -- 커서 열기 > select문 실행 > 결과셋에 커서 연결(참조) > 탐색 > 자바의 Iterator
loop
fetch 커서명 into 변수; -- 커서 사용 > 데이터 접근 > 조작 > select into와 동일한 역할
exit when vcursor%notfound; --커서가 더이상 다음 레코드를 발견하지 못할 때
end loop;
close 커서명; -- 커서 닫기
end;
b. cursor + for loop
declare
cursor 커서명 is select문;
변수 선언;
begin
for 변수명 in 커서명 loop --vcursor(결과 테이블 = 레코드집합)
실행문;
end loop;
end;
- cursor + loop
declare
cursor vcursor is select name from tblInsa;
vname tblInsa.name%type;
begin
open vcursor;
loop
fetch vcursor into vname;
-- boolean
exit when vcursor%notfound; --커서가 더이상 다음 레코드를 발견하지 못할 때
dbms_output.put_line(vname);
end loop;
close vcursor;
end;
- cursor + for loop
declare
cursor vcursor is
select * from tblInsa;
begin
-- open + loop + fetch into + vrow + exit when +
for vrow in vcursor loop --vcursor(결과 테이블 = 레코드집합)
dbms_output.put_line(vrow.name);
end loop;
end;
// 예외처리
- 실행부에서 발생하는 예외를 처리하는 블럭
declare
변수 선언;
begin
실행문;
exception
when 예외상수 then 처리;
end;
- 예외 상수
~ others : 모든 예외 ≒ catch(Exception e)
declare
vname varchar2(15);
begin
dbms_output.put_line('시작');
select name into vname from tblInsa; --레코드가 1개가 아니라서 에러 발생
dbms_output.put_line('종료');
exception
--when 예외상수 then 처리;
when others then --others: 모든 예외
dbms_output.put_line('예외 처리');
end;
declare
vcnt number;
vname varchar2(15);
begin
--1.
-- select count(*) into vcnt from tblCountry;
-- dbms_output.put_line(100 / vcnt);
--2.
select name into vname from tblInsa; -- where num = 1001;
dbms_output.put_line(vname);
exception
when ZERO_DIVIDE then
dbms_output.put_line('0으로 나누었습니다.');
insert into tblError values ((select nvl(max(seq), 0) + 1 from tblError), 'A001', default);
when TOO_MANY_ROWS then
dbms_output.put_line('가져온 행이 많습니다.');
insert into tblError values ((select nvl(max(seq), 0) + 1 from tblError), 'B001', default);
when others then
dbms_output.put_line('예외 처리');
insert into tblError values ((select nvl(max(seq), 0) + 1 from tblError), 'B002', default);
end;
select * from tblError order by regdate desc;
// 매개변수 모드
- 매개변수가 값을 전달하는 방식
- call by value
- call by reference
1. in 모드 > 기본 모드
- 키워드가 생략되어 있을 경우 in이 생략되어 있는 것
- 호출 때 넘기는 데이터
2. out 모드
- 변수 자체가 젼달된다.
- 변수의 주소값 전달
- 반환값 역할, but 여러 개를 사용할 수 있다.
3. in out 모드 > 거의 안 씀
create or replace procedure procTest (
pnum1 in number, --우리가 알고 있는 기존의 매개변수(호출 때 넘기는 데이터)
pnum2 in number,
presult1 out number, -- 변수 자체가 전달. 변수의 주소값 전달 > 반환값 역할
presult2 out number,
presult3 out number
)
is
begin
presult1 := pnum1 + pnum2;
presult2 := pnum1 * pnum2;
presult3 := pnum1 / pnum2;
end procTest;
declare
vresult1 number;
vresult2 number;
vresult3 number;
begin
procTest(10, 20, vresult1, vresult2, vresult3);
dbms_output.put_line(vresult1);
dbms_output.put_line(vresult2);
dbms_output.put_line(vresult3);
end;
-- 직원 번호 지정 > 같이 지역에 사는 직원 수, 같은 직위의 직원 수, 해당 직원보다 급여를 더 많이 받은 직원 수를 반환
-- in 1개 > out 3개
create or replace procedure procTest2(
pnum in number,
pcnt1 out number,
pcnt2 out number,
pcnt3 out number
)
is
vcity tblInsa.city%type;
vjikwi tblInsa.jikwi%type;
vbasicpay tblInsa.basicpay%type;
begin
select city, jikwi, basicpay into vcity, vjikwi, vbasicpay
from tblInsa where num = pnum;
select count(*) into pcnt1 from tblInsa
where city = vcity and num <> pnum;
select count(*) into pcnt2 from tblInsa
where jikwi = vjikwi and num <> pnum;
select count(*) into pcnt3 from tblInsa
where basicpay > vbasicpay;
end procTest2;
declare
vcnt1 number;
vcnt2 number;
vcnt3 number;
begin
procTest2(1001, vcnt1, vcnt2, vcnt3);
dbms_output.put_line(vcnt1);
dbms_output.put_line(vcnt2);
dbms_output.put_line(vcnt3);
end;
// SQL 처리 순서
- select문 실행
1. ANSI-SQL or PL/SQL - 익명 프로시저
a. 클라이언트 > 구문 작성(select)
b. > 실행(Ctrl+Enter)
c. 명령어를 오라클 서버로 전송
d. 서버 > 명령어 수신
e. > 파싱(토큰 단위로 분해) > 문법 검사
f. > 컴파일(기계어로)
g. > 실행(SQL)
h. > 결과셋 생성
i. > 결과셋을 클라이언트에게 반환
j. 클라이언트 > 결과셋을 받아 화면에 출력
- 동일한 명령어를 재실행해도 실행 비용이 항상 동일하다.
2. PL/SQL - 저장 프로시저(프로시저 or 함수)
a. 클라이언트 > 구문 작성(create)
b. > 실행(Ctrl+Enter)
c. 명령어를 오라클 서버로 전송
d. 서버 > 명령어 수신
e. > 파싱(토큰 단위로 분해) > 문법 검사
f. > 컴파일(기계어로)
g. > 실행(SQL)
h. > 프로시저 생성 > 영구 저장(하드디스크)
i. > 종료
a. 클라이언트 > 구문 작성(호출)
b. > 실행(Ctrl+Enter)
c. 명령어를 오라클 서버로 전송
d. 서버 > 명령어 수신
e. > 파싱(토큰 단위로 분해) > 문법 검사
f. > 컴파일(기계어로)
g. > 실행(SQL)
h. > 아까 컴파일 완료된 프로시저가 실행 > 프로시저에 관련된 작업 재사용ㅇ
i. > 결과셋 반환(select)
j. 클라이언트 > 결과셋을 받아 화면에 출력
- 동일한 명령어를 재실행할 때 반복 비용 저렴(컴파일된 프로시저 호출 > 파싱 + 컴파일 생략)
// 트리거
- 프로시저의 한 종류
- 개발자가 호출하는 것이 아니라, 미리 지정한 특정 사건이 발생하면 자동으로 실행되는 프로시저
- 예약(사건) > 사건 발생 > 프로시저 호출
- 특정 테이블 지정 > 감시(insert or update or delete) > 미리 준비해놓은 프로시저 호출
- 보통 트리거 선언 시 감시 대상 테이블을 구현부에서 조작하지 않는다.
create or replace trigger 트리거명
befor|after
insert|update|delete on 테이블명
[for each row]
[declare
선언부;]
begin
실행부;
[exception
예외처리부;]
end;
- 강제 예외 발생
~ raise_application_error(예외 번호, '에러 메시지');
- 예외 번호 지정: -20000 ~ 29999
- inserting | updating | deleting : insert | update | deleting 이 실행되었는지 여부를 담는 변수
- [for each row]
1. 사용 X
- 문장(Query) 단위 트리거
- 트리거 실행 1회
- 적용되는 행의 개수가 n개여도 프로시저 1회 호출 > 집단을 대상으로 실행
2. 사용 O
- 행(Record) 단위 트리거
- 트리거 실행 반복
- 적용되는 행의 개수만큼 프로시저 호출 > 개인을 대상으로 실행
- :old.컬럼 > 삭제 또는 수정되는 행 참조 객체
~ dbms_output.put_line('레코드를 삭제했습니다.' || :old.name);
~ delete from tblWomen where name = '하하하';
~ 레코드를 삭제했습니다.하하하
- :new.컬럼 > 새롭게 추가되거나 수정되는 행 참조 객체
~ dbms_output.put_line('레코드를 추가했습니다' || :new.name || :new.age);
~ insert into tblWomen values('호호호', 20, 160, 50, null);
~ 레코드를 추가했습니다.호호호20
create or replace trigger trgInsa
before --삭제하기 직전에 프로시저를 실행해라
delete --삭제가 발생하는지 감시해라
on tblInsa -- 감시대상 > tblInsa
begin
dbms_output.put_line('트리거가 실행되었습니다.');
end trgInsa;
delete from tblInsa where num = 1001;
create table tblLogMen (
seq number primary key,
message varchar2(1000) not null,
regdate date default sysdate not null
);
create sequence seqLogMen;
create or replace trigger trgLogMen
after
insert or update or delete
on tblMen
declare
vmessage varchar2(1000);
begin
dbms_output.put_line('트리거 실행');
-- 호출: insert ? update? delete?
if inserting then
dbms_output.put_line('새로운 항목이 추가되었습니다.');
vmessage := '새로운 항목이 추가되었습니다.';
elsif updating then
dbms_output.put_line('항목이 수정되었습니다.');
vmessage := '항목이 수정되었습니다.';
elsif deleting then
dbms_output.put_line('항목이 삭제되었습니다.');
vmessage := '항목이 삭제되었습니다.';
end if;
insert into tblLogMen values (seqLogMen.nextVal, vmessage, default);
end trgLogMen;
insert into tblMen values ('테스트', 22, 175, 60, null);
update tblMen set weight = 65 where name = '테스트';
delete from tblMen where name = '테스트';
select * from tblLogMen;
- 예외 발생
create or replace trigger trgRemoveInsa
before
delete on tblInsa
begin
dbms_output.put_line('트리거 실행');
--수요일 퇴사 금지
if to_char(sysdate, 'd') = '4' then
dbms_output.put_line('수요일');
raise_application_error(-20000, '수요일에는 퇴사가 불가능합니다.');
else
dbms_output.put_line('다른 요일');
end if;
end trgRemoveInsa;
delete from tblInsa where num = 1004;
- :new, :old
create or replace trigger trgWomen
after
insert
on tblWomen
for each row
begin
dbms_output.put_line(':old > ' || :old.name);
dbms_output.put_line(':new > ' || :new.name); -- 테스트
dbms_output.put_line(' ');
end trgWomen;
insert into tblWomen values ('테스트', 22, 175, 60, null);
create or replace trigger trgWomen
after
update
on tblWomen
for each row
begin
dbms_output.put_line(':old > ' || :old.weight);
dbms_output.put_line(':new > ' || :new.weight);
dbms_output.put_line(' ');
end trgWomen;
update tblWomen set weight = 65 where name = '테스트';
create or replace trigger trgWomen
after
delete
on tblWomen
for each row
begin
dbms_output.put_line(':old > ' || :old.name);
dbms_output.put_line(':new > ' || :new.name);
dbms_output.put_line(' ');
end trgWomen;
delete from tblWomen where name = '테스트';
// 커서를 반환하는 프로시저
- 결과셋을 반환(테이블을 통쨰로 반환)
- out 파라티머 > 가능
- return > 불가능
- sys_refcursor > 커서를 반환값으로 사용할 때 쓰는 자료형
create or replace procedure procBuseo(
pbuseo in varchar2,
pcursor out sys_refcursor -- 커서를 반환값으로 사용할 때 쓰는 자료형
)
is
begin
open pcursor
for
select * from tblInsa where buseo = pbuseo;
end procBuseo;
declare
vcursor sys_refcursor; -- 커서 참조 변수(out)
vrow tblInsa%rowtype;
begin
procBuseo('영업부', vcursor);
loop
fetch vcursor into vrow;
exit when vcursor%notfound;
dbms_output.put_line(vrow.name);
end loop;
end;
'데이터베이스(DB) > Oracle' 카테고리의 다른 글
[Oracle] 참조 레코드 삭제 (0) | 2023.03.29 |
---|---|
[Oracle] 일련번호 (0) | 2023.03.28 |
[Oracle] 복합키 (0) | 2023.03.24 |
[Oracle] 데이터베이스 설계 (0) | 2023.03.23 |
[Oracle] 계층형 쿼리 (0) | 2023.03.23 |