hyeonga_code
Database_86_PL/SQL_제어 구조_예외 처리 본문
-- PL/SQL 제어 구조
-- 예외 처리
-- 예외 : 프로그램 실행 중 발생한 오류입니다.
-- 발생하는 경우
-- 시스템 예외 : Oracle Server에 의해 암시적으로 발생합니다.
-- 사용자 정의 예외 : 프로그램에 의해 명시적으로 발생합니다.
-- 처리 방법
-- 처리기로 트랩
-- 호출 환경으로 전달
-- 예외를 프로그래밍하면 실행 중단을 방지할 수 있습니다.
-- 오류 발생 시 출력되는 기본 메세지를 확인합니다.
DECLARE
v_lname VARCHAR2(15);
BEGIN
SELECT last_name INTO v_lname
FROM employees
WHERE department_id = 50;
DBMS_OUTPUT.PUT_LINE ('John''s last name is :' ||v_lname);
END;
/
/*
-----<오류>---------------------------------------------------------------------
오류 보고 -
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 4
01422. 00000 - "exact fetch returns more than requested number of rows"
*Cause: The number specified in exact fetch is less than the rows returned.
*Action: Rewrite the query or change number of rows requested
--------------------------------------------------------------------------------
*/
-- 오류 발생 시 원하는 메세지를 출력할 수 있습니다.
SET SERVEROUTPUT ON;
DECLARE
v_lname VARCHAR2(15);
BEGIN
SELECT last_name INTO v_lname
FROM employees
WHERE department_id = 50;
DBMS_OUTPUT.PUT_LINE ('John''s last name is :' ||v_lname);
EXCEPTION
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE ('Your select statement retrieved multiple
rows.Consider using a cursor.');
END;
/
/*
Your select statement retrieved multiple rows.
Consider using a cursor.
PL/SQL 프로시저가 성공적으로 완료되었습니다.
*/
-- 구문
/*
EXCEPTION --미리 정의된 예외의 표준 이름 또는 사용자가 선언 부분에 정의한 예외의 이름
WHEN exception1 [OR exception2 . . .] THEN
statement1; --하나 이상의 PL/SQL 또는 SQL 문
statement2;
. . .
[WHEN exception3 [OR exception4 . . .] THEN
statement1;
statement2;
. . .]
[WHEN OTHERS THEN --지정되지 않은 예외를 트랩하는 선택적 예외 처리 절
statement1;
statement2;
. . .]
*/
-- PL/SQL 블록의 예외 처리 부분에 해당 루틴을 포함시켜 오류를 트랩할 수 있습니다.
-- 각 처리기는 예외를 지정하는 WHEN 절과 예외 발생 시 실행될 일련의 명령문으로 구성됩니다.
-- 주의 사항
-- 예외 처리 섹션은 EXCEPTION 키워드로 시작합니다.
-- 블록에 대해 각각 고유의 작업 집합을 가진 여러 개의 예외 처리기를 정의합니다.
-- 예외가 발생하면 PL/SQL은 하나의 처리기만 거친 뒤 블록을 종료합니다.
-- WHEN OTHERS는 마지막 절입니다.
-- 예외 유형
-- 미리 정의된 Oracle Server 오류
/*
BEGIN
. . .
EXCEPTION
WHEN NO_DATA_FOUND THEN
statement1;
statement2;
WHEN TOO_MANY_ROWS THEN
statement1;
WHEN OTHERS THEN
statement1;
statement2;
statement3;
END;
*/
-- PL/SQL 코드에서 자주 발생하는 약 20가지 오류 중 하나입니다.
-- Oracle Server가 암시적으로 실행하므로 선언하지 않습니다.
-- 예제
-- 항상 처리하는 것이 좋은 예제
-- NO_DATA_ROUND
-- TOO_MANY_ROWS
-- INVALID_CURSOR
-- ZERO_DIVIDE
-- DUP_VAL_ON_INDEX
-- 미리 정의되지 않은 Oracle Server 오류
-- 다른 표준 Oracle Server 오류입니다.
-- 선언 부분에서 선언합니다.
-- Oracle Server가 암시적으로 발생시킵니다.
-- 오류를 먼저 선언하거나 OTHERS 처리기를 사용합니다.
-- 사용자가 정의한 오류
-- 개발자가 비정상이라고 판단하는 조건입니다.
-- 선언 부분에서 선언합니다.
-- 명시적으로 발생시킵니다.
-- 미리 정의되지 않은 Oracle Server 오류 트랩
-- 다음 PL/SQL은 Oracle Server 오류 01400 (“cannot insert NULL”)을 트랩합니다.
DECLARE
e_insert_excep EXCEPTION; --선언 부분에 예외의 이름을 선언
--앞에서 선언한 예외와 표준 Oracle Server 오류 번호를 연결
PRAGMA EXCEPTION_INIT(e_insert_excep, -01400);
BEGIN
INSERT INTO departments
(department_id, department_name) VALUES (280, NULL);
EXCEPTION
WHEN e_insert_excep THEN --선언한 예외를 해당 예외 처리 루틴에서 참조
DBMS_OUTPUT.PUT_LINE('INSERT OPERATION FAILED');
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/
/*
INSERT OPERATION FAILED
ORA-01400: cannot insert NULL into ("HR"."DEPARTMENTS"."DEPARTMENT_NAME")
PL/SQL 프로시저가 성공적으로 완료되었습니다
*/
-- 예외 트랩 관련 함수
-- 발생한 예외 정보를 참조하기 위한 수단입니다.
-- SQLCODE : 오류 코드의 숫자 값을 반환합니다.
-- SQLERRM : 오류 번호와 연관된 메세지를 반환합니다.
-- SQLCODE는 “-1476”을, SQLERRM은 “ORA-01476: divisor is equal to zero”를 반환합니다.
DECLARE
vi_num NUMBER := 0;
BEGIN
vi_num := 10 / 0;
DBMS_OUTPUT.PUT_LINE('Success!');
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('오류가 발생했습니다');
DBMS_OUTPUT.PUT_LINE('SQL ERROR CODE:' || SQLCODE);
DBMS_OUTPUT.PUT_LINE('SQL ERROR MESSAGE:' || SQLERRM);
END;
/
/*
오류가 발생했습니다
SQL ERROR CODE:-1476
SQL ERROR MESSAGE:ORA-01476: divisor is equal to zero
PL/SQL 프로시저가 성공적으로 완료되었습니다.
*/
-- RAISE 문
/*
RAISE exception_name;
*/
-- PL/SQL 블록이나 서브 프로그램의 정상적인 실행을 정지하고 컨트롤을 예외 처리기로 전달합니다.
-- 미리 정의된 예외나 유저가 정의한 예외를 명시적으로 발생시킵니다.
-- 예외를 발생시키면 자동으로 제어권이 EXCEPTION 절로 넘어옵니다.
-- 시스템 예외와 동일한 방식으로 처리합니다.
-- RAISE_APPLICATION_ERROR
/*
RAISE_APPLICATION_ERROR ( error_number, message[, { TRUE | FALSE } ] );
-- error_number : 사용자가 예외에 지정하는 번호입니다.
-- message : 사용자가 예외에 지정하는 메세지입니다.
-- TRUE | FALSE(기본값)
-- TRUE : 이전 오류 스텍에 해당 오류가 추가됩니다.
-- FALSE : 모든 오류를 해당오류로 대체합니다.
*/
-- 사용 위치
-- PL/SQL 프로그램의 실행 부분
-- EXCEPTION_예외 섹션
DECLARE
v_deptno NUMBER := 500;
v_name VARCHAR2(20) := 'Testing';
e_invalid_department EXCEPTION; --사용자가 정의한 예외의 이름을 선언 부분에서 선언
BEGIN
UPDATE departments
SET department_name = v_name
WHERE department_id = v_deptno;
IF SQL%NOTFOUND THEN
RAISE e_invalid_department; --실행 부분에서 RAISE 문을 사용하여 예외를 명시적으로 발생
END IF;
COMMIT;
EXCEPTION
WHEN e_invalid_department THEN --선언한 예외를 해당 예외 처리 루틴에서 참조
DBMS_OUTPUT.PUT_LINE('No such department id.');
END;
/
/*
No such department id.
PL/SQL 프로시저가 성공적으로 완료되었습니다.
*/
DECLARE
v_deptno NUMBER := 500;
v_name VARCHAR2(20) := 'Testing';
BEGIN
UPDATE departments
SET department_name = v_name
WHERE department_id = v_deptno;
IF SQL%NOTFOUND THEN
RAISE_APPLICATION_ERROR (-20000, 'No such department id.');
DBMS_OUTPUT.PUT_LINE('Department updated successfully.');
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/
/*
ORA-20000: No such department id.
PL/SQL 프로시저가 성공적으로 완료되었습니다.
*/
'Oracle Database' 카테고리의 다른 글
Database_88_함수 (0) | 2023.09.01 |
---|---|
Database_87_서브 프로그램 (0) | 2023.09.01 |
Database_85_PL/SQL_제어 구조_CURSOR (0) | 2023.08.31 |
Database_84_PL/SQL_제어 구조_반복 제어문 (0) | 2023.08.31 |
Database_83_PL/SQL_제어 구조_조건 제어문 (0) | 2023.08.31 |