예외 처리 Oracle PL/SQL(예제)
PL/SQL의 예외 처리란 무엇입니까?
PL/SQL 엔진이 런타임 시 발생하는 오류로 인해 실행할 수 없는 명령을 발견하면 예외가 발생합니다. 이러한 오류는 컴파일 시 캡처되지 않으므로 런타임에만 처리해야 합니다.
예를 들어, PL/SQL 엔진이 숫자를 '0'으로 나누라는 명령을 받으면 PL/SQL 엔진은 이를 예외로 처리합니다. 예외는 PL/SQL 엔진에 의해 런타임에만 발생합니다.
예외는 프로그램이 더 이상 실행되지 않도록 하므로 이러한 상황을 방지하려면 별도로 캡처하여 처리해야 합니다. 이 프로세스를 예외 처리라고 하며, 런타임 시 발생할 수 있는 예외를 프로그래머가 처리합니다.
예외 처리 구문
예외는 블록 수준에서 처리됩니다. 즉, 어떤 블록에서든 예외가 발생하면 해당 블록의 실행 부분에서 제어가 나옵니다. 그러면 해당 블록의 예외 처리 부분에서 예외가 처리됩니다. 예외를 처리한 후에는 해당 블록의 실행 섹션으로 제어를 다시 보낼 수 없습니다.
아래 구문은 예외를 포착하고 처리하는 방법을 설명합니다.
BEGIN <execution block> . . EXCEPTION WHEN <exceptionl_name> THEN <Exception handling code for the “exception 1 _name’' > WHEN OTHERS THEN <Default exception handling code for all exceptions > END;
구문 설명:
- 위 구문에서 예외 처리 블록에는 예외를 처리하기 위한 일련의 WHEN 조건이 포함되어 있습니다.
- 각 WHEN 조건 뒤에는 런타임 시 발생할 것으로 예상되는 예외 이름이 옵니다.
- 런타임 시 예외가 발생하면 PL/SQL 엔진은 예외 처리 부분에서 해당 특정 예외를 찾습니다. 첫 번째 'WHEN' 절부터 시작하여 순차적으로 검색합니다.
- 발생한 예외에 대한 예외 처리를 찾은 경우 해당 특정 처리 코드 부분을 실행합니다.
- 발생한 예외에 대해 'WHEN' 절이 없으면 PL/SQL 엔진은 'WHEN OTHERS' 부분(있는 경우)을 실행합니다. 이는 모든 예외에 공통적입니다.
- 예외를 실행한 후 부품 제어는 현재 블록에서 나옵니다.
- 런타임 시 블록에 대해 하나의 예외 부분만 실행할 수 있습니다. 이를 실행한 후 컨트롤러는 나머지 예외 처리 부분을 건너뛰고 현재 블록에서 나갑니다.
참고 : WHEN OTHERS는 항상 시퀀스의 마지막 위치에 있어야 합니다. WHEN OTHERS 이후에 존재하는 예외 처리 부분은 WHEN OTHERS를 실행한 후 제어가 블록에서 종료되므로 실행되지 않습니다.
예외 유형
에는 두 가지 유형의 예외가 있습니다. PL/SQL.
- 사전 정의된 예외
- 사용자 정의 예외
사전 정의된 예외
Oracle 몇 가지 일반적인 예외가 미리 정의되어 있습니다. 이러한 예외에는 고유한 예외 이름과 오류 번호가 있습니다. 이러한 예외는 이미 'STANDARD' 패키지에 정의되어 있습니다. Oracle. 코드에서는 미리 정의된 예외 이름을 직접 사용하여 처리할 수 있습니다.
다음은 미리 정의된 몇 가지 예외입니다.
예외 | 에러 코드 | 예외사유 |
---|---|---|
ACCESS_INTO_NULL | ORA-06530 | 초기화되지 않은 개체의 속성에 값을 할당합니다. |
CASE_NOT_FOUND | ORA-06592 | CASE 문의 'WHEN' 절이 충족되지 않았고 'ELSE' 절이 지정되지 않았습니다. |
COLLECTION_IS_NULL | ORA-06531 | 컬렉션 메서드(EXISTS 제외) 사용 또는 초기화되지 않은 컬렉션의 컬렉션 속성에 액세스 |
CURSOR_ALREADY_OPEN | ORA-06511 | 열려고하는 중 커서 이미 열려 있는 것 |
DUP_VAL_ON_INDEX | ORA-00001 | 고유 인덱스로 제한된 데이터베이스 열에 중복 값 저장 |
INVALID_CURSOR | ORA-01001 | 열리지 않은 커서를 닫는 것과 같은 불법적인 커서 작업 |
잘못된 번호 | ORA-01722 | 잘못된 숫자 문자로 인해 문자를 숫자로 변환하지 못했습니다. |
데이터가 없습니다 | ORA-01403 | INTO 절이 포함된 'SELECT' 문이 행을 가져오지 않는 경우. |
ROW_MISMATCH | ORA-06504 | 커서변수의 데이터형이 실제 커서 반환형과 호환되지 않는 경우 |
SUBSCRIPT_BEYOND_COUNT명 | ORA-06533 | 컬렉션 크기보다 큰 인덱스 번호로 컬렉션 참조 |
SUBSCRIPT_OUTSIDE_LIMIT | ORA-06532 | 법적 범위를 벗어난 색인 번호로 수집 참조(예: -1) |
TOO_MANY_ROWS | ORA-01422 | INTO 절이 포함된 'SELECT' 문이 두 개 이상의 행을 반환하는 경우 |
VALUE_ERROR | ORA-06502 | 산술 또는 크기 제약 오류(예: 변수 크기보다 큰 변수에 값 할당) |
ZERO_DIVIDE | ORA-01476 | 숫자를 '0'으로 나누기 |
사용자 정의 예외
In Oracle, 위에 미리 정의된 예외 외에 프로그래머는 자신만의 예외를 만들어 처리할 수 있습니다. 선언 부분의 하위 프로그램 수준에서 생성할 수 있습니다. 이러한 예외는 해당 하위 프로그램에서만 볼 수 있습니다. 패키지 사양에 정의된 예외는 공개 예외이며 패키지에 액세스할 수 있는 모든 곳에서 볼 수 있습니다.
구문 : 하위 프로그램 수준에서
DECLARE <exception_name> EXCEPTION; BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> END;
- 위 구문에서 변수 'Exception_name'은 'EXCEPTION' 유형으로 정의됩니다.
- 이는 미리 정의된 예외와 비슷한 방식으로 사용될 수 있습니다.
구문 :패키지 사양 수준에서
CREATE PACKAGE <package_name> IS <exception_name> EXCEPTION; . . END <package_name>;
- 위 구문에서 'Exception_name' 변수는 패키지 사양에서 'EXCEPTION' 유형으로 정의되어 있습니다. .
- 이는 'package_name' 패키지가 호출될 수 있는 데이터베이스에서 사용할 수 있습니다.
PL/SQL 발생 예외
오류가 발생할 때마다 미리 정의된 모든 예외가 암시적으로 발생합니다. 그러나 사용자 정의 예외는 명시적으로 발생해야 합니다. 이는 'RAISE'라는 키워드를 사용하여 달성할 수 있습니다. 이는 아래에 언급된 방법 중 하나로 사용될 수 있습니다.
프로그램에서 'RAISE'를 별도로 사용하면 이미 발생한 예외가 상위 블록에 전파됩니다. 아래와 같이 예외 블록에서만 사용할 수 있습니다.
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> RAISE; END;
구문 설명:
- 위 구문에서는 예외 처리 블록에 RAISE 키워드가 사용되었습니다.
- 프로그램에서 "Exception_name" 예외가 발생할 때마다 해당 예외가 처리되고 정상적으로 완료됩니다.
- 그러나 예외 처리 부분의 'RAISE' 키워드는 이 특정 예외를 상위 프로그램에 전파합니다.
참고 : 부모 블록에서 예외를 발생시키는 동안 발생되는 예외는 부모 블록에서도 표시되어야 합니다. 그렇지 않으면 Oracle에서 오류가 발생합니다.
- 특정 사용자 정의/미리 정의된 예외를 발생시키기 위해 키워드 'RAISE'와 예외 이름을 사용할 수 있습니다. 이는 실행 부분과 예외 처리 부분 모두에서 예외를 발생시키는 데 사용될 수 있습니다.
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> RAISE <exception_name> EXCEPTION WHEN <exception_name> THEN <Handler> END;
구문 설명:
- 위 구문에서는 실행 부분에 RAISE 키워드가 사용되고 예외 "Exception_name"이 뒤따릅니다.
- 이로 인해 실행 시 특정 예외가 발생하므로 이를 처리하거나 추가로 발생시켜야 합니다.
예제 1: 이 예에서는
- 예외를 선언하는 방법
- 선언된 예외를 발생시키는 방법 및
- 메인 블록에 전파하는 방법
DECLARE Sample_exception EXCEPTION; PROCEDURE nested_block IS BEGIN Dbms_output.put_line(‘Inside nested block’); Dbms_output.put_line(‘Raising sample_exception from nested block’); RAISE sample_exception; EXCEPTION WHEN sample_exception THEN Dbms_output.put_line (‘Exception captured in nested block. Raising to main block’); RAISE, END; BEGIN Dbms_output.put_line(‘Inside main block’); Dbms_output.put_line(‘Calling nested block’); Nested_block; EXCEPTION WHEN sample_exception THEN Dbms_output.put_line (‘Exception captured in main block'); END: /
코드 설명 :
- 코드 라인 2: 'sample_Exception' 변수를 EXCEPTION 유형으로 선언합니다.
- 코드 라인 3: Nested_block 프로시저를 선언합니다.
- 코드 라인 6: "내부 중첩 블록"이라는 문을 인쇄합니다.
- 코드 라인 7: "중첩 블록에서 샘플_예외 발생"이라는 문을 인쇄합니다.
- 코드 라인 8: 'RAISE Sample_Exception'을 사용하여 예외를 발생시킵니다.
- 코드 라인 10: 중첩된 블록의 예외 샘플_예외에 대한 예외 처리기입니다.
- 코드 라인 11: '내포된 블록에서 예외가 캡처되었습니다'라는 문을 인쇄합니다. 메인 블록으로 올리기 '.
- 코드 라인 12: 메인 블록에 대한 예외 발생(메인 블록으로 전파)
- 코드 라인 15: "메인 블록 내부"라는 문구를 인쇄합니다.
- 코드 라인 16: "내포된 블록 호출" 명령문을 인쇄합니다.
- 코드 라인 17: nested_block 프로시저를 호출합니다.
- 코드 라인 18: 예외
- 코드 라인 19: 메인 블록의 Sample_Exception에 대한 예외 처리기입니다.
- 코드 라인 20: "메인 블록에서 예외가 캡처되었습니다."라는 문장을 인쇄합니다.
Exception에서 주의할 중요한 사항
- 함수에서 예외는 항상 값을 반환하거나 예외를 더 발생시켜야 합니다. 또 다른 Oracle 런타임 시 '값 없이 반환된 함수' 오류가 발생합니다.
- 트랜잭션 제어문은 예외 처리 블록에 제공될 수 있습니다.
- SQLERRM 및 SQLCODE는 예외 메시지 및 코드를 제공하는 내장 함수입니다.
- 예외가 처리되지 않으면 기본적으로 해당 세션의 모든 활성 트랜잭션이 롤백됩니다.
- RAISE_APPLICATION_ERROR(- , )를 RAISE 대신 사용하여 사용자 코드 및 메시지로 오류를 발생시킬 수 있습니다. 오류 코드는 20000보다 커야 하며 앞에 '-'가 붙어야 합니다.
요약
이 장을 마친 후에는 다음과 같은 Pl의 측면에 대해 작업할 수 있어야 합니다. SQL 예외
- 예외 처리
- 예외 정의
- 예외 발생
- 예외 전파