24.07.11(목) FORALL/EXCEPTION HANDING/ RAISE
7.11(목)
유니크한 인덱스 생성되는 조건
- primary key제약조건, unique 제약조건을 걸면 유니크한 인덱스가 생성된다.
그 외에는 non unique한 인덱스를 생성해야 한다.
◎ BULK COLLECT INTO 어디에 쓰여?
1. SELECT절 --7.10일 수업내용
2. FETCH절 --7.11일 수업내용
3. RETURNING절 --7.11일 수업내용
◎ FORALL
--FORALL문은 PL/SQL 엔진에서 SQL엔진 사이의 문맥 전환을 줄이는 문
왜 문맥 전환이 일어나?
배열변수 안에 값을 이용해서 DML문장 반복해야할 때 사용한다.
문맥전환을 여러번할 거 1번만 BULK처럼 한꺼번에 전달
FORALL문을 이용하면 PL/SQL 엔진이 DML문을 이용해서 bind하여 SQL 엔진한테 보내면 문맥 전환이 한 번으로 끝난다.
-- DELETE/ INSERT/ UPDATE만 쓸 수 있어! (SELECT문은 불가능)
◎ 예외처리(EXCEPTION HANDLING)
EXCEPTION 오류이름 THEN
어떻게 처리해.
- EXCEPTION절에서 예외처리
- 여러 예외 처리기를 사용할 수 있다.
- 실행 중에 발생한 오류에 따른 하나의 처리기만 수행하고 끝난다.
- WHEN others THEN 절은 마지막 절이다.
# sqlcode : 오류 코드에 대한 숫자값을 반환한다.
# sqlerrm : 오류번호와 연관된 메세지를 반환한다.
# 미리 정의 되지 않은 오라클 서버 오류
정의되지 않았으니 DECLARE절에 정의시켜줘야지.
이 오류번호가 뜰 때는 이 이름을 붙여줘.
-- 이름붙여주기 : 오류이름 EXCEPTION;
PRAGMA EXCEPTION_INIT(생성한 이름, 오라클 오류번호);
오류발생 케이스
1번째 케이스 : 프로그램이 비정상적으로 종료되면 프로그램 안에서 수행되던 transaction은 자동 ROLLBACK처리가 됨
2번째 케이스 : 예외처리 한 경우 오류 앞단에 수행하고 있던 transaction은 진행중인 상태이기때문에 꼭 transaction을 종료해야해!
3번째 케이스 : main block과 sub block을 이용해서 EXCEPTION HANDLING한 후에도 이후 과정을 수행하게할 수 있어.
4번째 케이스 : sub block안에 exception handling이 없는경우 main block안에 있는 exception handling을 찾는다. 그래서 이후에 있는 DML select절은 수행되지 않아.
-- RAISE문
DECLARE
이름 EXCEPTION; --exception 이름 선언
RAISE 이름; --RAISE문은 사용자가 정의한 예외사항을 사용할 때 사용하는 문. RAISE문을 만나는 순간 무조건
# RAISE_APPLICATION_ERROR(오류번호, 오류메세지, false(ture)) --기본값은 false
-- 오류나게 해서 프로그램이 비정상적으로 끝내도록 하는 방법
-- 비정상 종료될 때 유저 정의 오류 메세지를 실행하는 프로시저 프로그램
오류번호 규칙 : -20000 ~ -20999
오류 메세지 규칙: 최대 2048byte 문자열
false : 기본값, 오라클의 오류는 내가 만든 오류로 출력된다.
ture : 오라클의 오류와 내가 만든 오류가 같이이 출력된다.
--오류나게 해서 프로그램이 비정상적으로 끝내도록 하는 방법도 필요하다
IF sql%NOTFOUND THEN
RAISE_APPLICATION_ERROR(-20000,'수정된 데이터가 없습니다.');
◎ FORALL문의 EXCEPTION HANDLING
-- FORALL문 오류번호 : -24381(고정)
# SAVE EXCEPTIONS : 문제가 되는 애들은 save시켜놔 그리고 넘어가서 수행해!
# sql%bulk_rowcount : 몇건이 영향을 입은 건수인지 카운트
# sql%bulk_exceptions.count : FORALL문 수행시 save exception한 수를 리턴, 오류 발생한 건수 리턴
# sql%bulk_exceptions(오류발생수).error_index : 오류발생한 배열의 인덱스 번호를 리턴
# sqlerrm(-sql%bulk_exceptions(j).error_code) : 문제 파악을 위해서 실제 오류를 봐야할 때 사용
-- FORALL은 벌크로 하니까!