PL/SQL을 작성하면서 볼 수 있는 에러입니다. PL/SQL 내에서 SELECT문을 사용하여 테이블에서 어떤 조건에 맞는 데이터를 검색해 INTO 절을 사용하여 데이터를 입력하려 할 때, 조건에 맞는 데이터가 없는, 조건에 맞는 데이터가 0건인 경우 발생하는 에러입니다.
BEGIN
...
SELECT user_name
INTO vs_user_name
FROM users
WHERE user_id = 123456;
...
END;
위 PL/SQL 에서 user_id가 123456인 사용자가 없으면 반환되는 Row 수는 0이 됩니다. 이럴 때 발생하게 됩니다.
해결방법은 3가지가 있습니다만 편법도 있고, 실행 과정에서 에러 처리로 실행이 중단되게 되므로 상황에 맞게 사용하면 됩니다.
1. EXCEPTION 처리
가장 기본적인 방법은 EXCEPTION 처리해주는 방법이 있습니다.
BEGIN
...
SELECT user_name
INTO vs_user_name
FROM users
WHERE user_id = 123456;
...
EXCEPTION
WHEN NO_DATA_FOUND THEN
예외처리구문1;
예외처리구문2;
...
END;
위와 같이 EXCEPTION 처리를 해주면 데이터가 없더라도 에러는 발생하지 않습니다.
그러나 EXCEPTION이 발생하면 처리 순서가 EXCEPTION 구문으로 분기한 다음 구현한 예외처리 구문들을 실행하고 PL/SQL이 종료하게 됩니다. 만약 ROW가 없더라도 추가적으로 실행할 구문이 있다면 적합한 방법은 아닙니다.
아래 두가지 방법을 사용하면 ROW가 없을 경우 null을 반환 값으로 받을 수 있습니다.
2. MAX, MIN 함수 사용
그룹 함수인 MAX, MIN 함수를 사용할 수 있습니다.
SELECT문에서 값이 있을 경우에 MAX, MIN 결과가 실행에 영향을 미치지 않는다면 간단히 처리할 수 있습니다.
BEGIN
...
SELECT MAX(user_name)
INTO vs_user_name
FROM users
WHERE user_id = 123456;
...
END;
위와 같이 MAX와 같은 그룹 함수를 사용하면 ROW가 없을 경우 결과로 null을 반환하게 됩니다.
문제는 해결할 수 있지만 SQL 문의 가독성은 떨어지게 됩니다.
3. SELECT ... FROM DUAL
BEGIN
...
SELECT (
SELECT user_name
FROM users
WHERE user_id = 123456 )
INTO vs_user_name
FROM DUAL;
...
END;
FROM DUAL을 사용하여 서브 쿼리 형태로 사용하면 반환하는 ROW 0수가 0이 될 경우 null을 반환하게 되며 에러는 나지 않습니다. 만약 2번처럼 그룹 함수를 사용할 수 없을 경우 사용할 수 있습니다만 서브 쿼리 형태가 되므로 PL/SQL문이 좀 더 길어지게 되는 단점이 있습니다.
'Dev. Cookbook > SQL, Oracle, MariaDB' 카테고리의 다른 글
[Oracle] ORA-08002: 시퀀스 xxx.CURRVAL은 이 세션에서는 정의 되어 있지 않습니다 (0) | 2022.05.27 |
---|---|
[Oracle] sys, system 계정 비밀번호 재설정 방법 (0) | 2022.05.24 |
[Oracle] Select count(*), count(1), count(column_name), count(DISTINCT column_name) 차이점 (0) | 2022.05.12 |
[Oracle] Cursor와 ROWCOUNT에 대해 이해하기 (0) | 2022.05.06 |
[ORACLE] 시노님(Synonym) 삭제 오류, ORA-01434 : private synonym to be dropped does not exist (0) | 2022.04.26 |
댓글