본문 바로가기

DB/Oracle

PL/SQL의 예외 처리 (EXCEPTION WHEN)

EXCEPTION문에 의한 예외 처리

PL/SQL의 BEGIN과 END간에 발생한 예외는, 그 블록중에서 정의한 EXCEPTION 문장으로 취급한다.
같은 블록으로 예외 처리가 정의되어 있지 않은 경우에는 상위의 블록에 정의한다.
예외를 캐치해도 예외 처리부에서 아무것도 처리를 하지 않으면 아무것도 하지 않는다. 단.[예외의 재호출]을 실행하지
않으면 블록내에서 예외의 처리가 실행되었다고 판단되어 상위의 블록에 예외가 전해지지 않게된다.

예외를 처리하는 것만으로는 PL/SQL은 트랜잭션(transaction)의 롤백(rollback)이나 어떠한 초기화도 행하지 않는다.
트랜잭션(transaction) 처리도 포함해 모두 유저프로그램에 맡길 수 있다.SQL 에러에 의한 문장 레벨의 롤백(rollback)은
예외처리에 관계없이 발생한다.
BEGIN
   <프로그램 본체>
EXCEPTION
 WHEN <예외명> THEN
   <예외 처리>
END;
=> 사전에 정의 끝난 예외의 이름
예외 처리 PL/SQL 블록정의
예외 처리는 WHEN문을 복수 기술하는 경우 분류 해 처리할 수 있다.
복수의 예외를 동시에 처리하고 싶은 경우에는 WHEN 예외명 or 예외명 or ... 과 같이 한다.

Ex) 모든 예외가 발생해도 아무것도 없었던 것으로 종료한다.(메세지는 표시되지 않는다.)
DECLARE
	vNum	NUMBER(2);
BEGIN
	vNum := 1 / 0;
	DBMS_OUTPUT.PUT_LINE('수치=' || vNum);
EXCEPTION
	WHEN OTHERS THEN
		NULL; -- NULL; 는 아무것도 하지 않는다고 하는 명령
END;

OTHERS 예외는 특별한 예외명으로, 모든 예외를 나타낼 수 있지만, OTHERS는 다른 예외와 함께 사용할 수 없다.

복수 예외 처리 기술과 상위 예외의 전송
0으로 나누었을 때 예외가 발생했을 경우 에러메세지를 표시한다. 0으로 나누었을 때 예외 발생시에는 다른 예외를
실행시키지 않는다. 0으로 나누었을 때 이외의 모든 예외 발생의 경우에는  <예외 처리>를 실행해 RAISE를 사용해 예외 정보를 보여준다.
DECLARE
	vNum	NUMBER(2);
BEGIN
	-- ZERO DIVIDE EXCEPTION
	vNum := 1 / 0;
	DBMS_OUTPUT.PUT_LINE('수치=' || vNum);
EXCEPTION
	WHEN ZERO_DIVIDE THEN
		DBMS_OUTPUT.PUT_LINE('계산할 수 없었습니다');
	WHEN OTHERS THEN
	--	< 예외 처리 > 
		RAISE;
END;

OTHERS 예외는, 모든 예외를 포괄하는 예외명이며, 예외 처리의 마지막에 기술 해야한다 아니면 compile error가 된다.

계층적인 블록의 예외 처리

블록의 구조는 계층적으로 하는 것이 가능
루프 처리의 내부에서 핸들링 가능한 예외가 발생할 가능성을 가지고 있는 경우, 그 처리 루프로부터 빠져 나가지 않게 하는것이 가능
DECLARE
	vNum	NUMBER(2);
BEGIN
	BEGIN
		-- ZERO DIVIDE EXCEPTION
		vNum := 1 / 0;
	EXCEPTION
		WHEN ZERO_DIVIDE THEN
			NULL;
	END;
EXCEPTION
	WHEN OTHERS THEN
		< 예외 처리 > 
		RAISE;
END;