다연이네

[days16] PL/SQL 블록 내에서 에러처리 본문

Oracle

[days16] PL/SQL 블록 내에서 에러처리

 다연  2020. 11. 19. 23:52
반응형

NO_DATA_FOUND ORA-01403  SQL문에 의한 검색조건을 만족하는 결과가 전혀 없는 조건의 경우 
NOT_LOGGED_ON ORA-01012  데이터베이스에 연결되지 않은 상태에서 SQL문 실행하려는 경우 
TOO_MANY_ROWS ORA-01422  SQL문의 실행결과가 여러 개의 행을 반환하는 경우, 스칼라 변수에 저장하려고 할 때 발생 
VALUE_ERROR   ORA-06502  PL/SQL 블럭 내에 정의된 변수의 길이보다 큰 값을 저장하는 경우 
ZERO_DEVIDE   ORA-01476  SQL문의 실행에서 컬럼의 값을 0으로 나누는 경우에 발생 
INVALID_CURSOR ORA-01001  잘못 선언된 커서에 대해 연산이 발생하는 경우 
DUP_VAL_ON_INDEX ORA-00001  이미 입력되어 있는 컬럼 값을 다시 입력하려는 경우에 발생 

 

 

 

create or replace procedure up_exception_test
(
    pdeptno number
)
is
 vename emp.ename%type;
begin
 select ename into vename
 from emp
 where deptno = pdeptno;
 dbms_output.put_line(vename);
exception
    when NO_DATA_FOUND then
     raise_application_error(-20003, '사원을 찾을 수 없다.'); --내가 원하는 에러 메세지를 발생시키겠다, 항상 -는 필수, -임의숫자
    when TOO_MANY_ROWS then
     raise_application_error(-20001, '여러명의 사원을 찾았다.');  --이 코드들은 임의대로 준 것 
    when others then 
     raise_application_error(-20004, '그 외의 에러가 발생했다.');
end;
--Procedure UP_EXCEPTION_TEST이(가) 컴파일되었습니다.

exec UP_EXCEPTION_TEST(10);
--오류 보고 -
--ORA-20001: 여러명의 사원을 찾았다.
exec UP_EXCEPTION_TEST(50);
--오류 보고 -
--ORA-20003: 사원을 찾을 수 없다.

 

 

미리 정의되지 않은 에러 처리방법 미리 정의된 에러 처리방법외에 사용자가 직접 에러 처리에 대한 논리적 흐름을 구현할 수 있다.
[PRAGMA EXCEPTION]절은 오라클 서버에서 어떤 에러 코드가 발생할 때 정의한 조건명을 지정할 것인지를 정의하는 절이다.

 

INSERT INTO emp (empno, ename, job, mgr, hiredate, sal, comm,deptno)
   values(8888, 'hong', 'CLERK', 7369, sysdate, 700, null, 90);

--90번 부서가 존재하지 않기 때문에 참조 무결성 오류가 떨어진다
--ORA-02291: integrity constraint (SCOTT.FK_DEPTNO) violated - parent key not found

 

 

사원을 INSERT하는 저장 프로시저

create or replace procedure up_insertemp
(
    pempno emp.empno%type
    ,pename emp.ename%type
    ,pjob emp.job%type
    ,pmgr emp.mgr%type
    ,phiredate emp.hiredate%type
    ,psal emp.sal%type
    ,pcomm emp.comm%type
    ,pdeptno emp.deptno%type
)
is
 e_invalid_deptno exception; --자료형에 exception을 줌
 --예외객체를 하나 선언 한 것
 --위 쿼리의 ORA-02291 예외랑 내가 새로 선언한 예외랑 연결할 때 프라그마 익셉션 사용
 PRAGMA exception_init(e_invalid_deptno, -02291);
begin
 INSERT INTO emp (empno, ename, job, mgr, hiredate, sal, comm,deptno)
   values(pempno, pename, pjob, pmgr, phiredate, psal, pcomm, pdeptno);
   commit;
exception
 when e_invalid_deptno then
 raise_application_error(-20202, '잘못된 부서 번호');
end;

exec up_insertemp(8888, 'hong', 'CLERK', 7369, sysdate, 700, null, 90);

 

 

사용자가 정의한 에러 처리방법
사용자가 미리 에러에 대한 정의를 하는 경우이며, EXCEPTION 키워드에 의해 에러 조건명을 정의하고 RAISE 명령어에 의해 에러가 발생되면 exception 절에서 에러가 처리된다.
== 자바의 throw와 똑같다

 

create or replace procedure up_test
(
    psal emp.sal%type
)
is
 vlowsal emp.sal%type := psal-100;
 vhighsal emp.sal%type := psal+100;
 vnoemp number(7,2); --인원수
 
 e_no_emp_returned exception; --사원이 아무도 없을때 발생시키는 예외 객체
 e_more_than_one_emp exception; -- 사원이 많을 때
begin
 select count(ename) into vnoemp
 from emp
 where sal between vlowsal and vhighsal;
 
 if vnoemp = 0 then
    raise e_no_emp_returned; --raise == 자바의 throw
 elsif vnoemp >1 then
    raise e_more_than_one_emp;
 else   dbms_output.put_line('1명 존재~');
 end if;
exception
 when e_no_emp_returned then 
    dbms_output.put_line('There is no employee salary...');
 when e_more_than_one_emp then
    dbms_output.put_line('There is a row employee...');
 when others then
    dbms_output.put_line('Any other error occured...');
end;


exec up_test(5000);
exec up_test(9000);

5000 - 9000

 

반응형
Comments