오라클 데이터베이스를 운영하거나 PL/SQL 프로시저 및 패키지를 개발할 때 가장 흔히 마주치는 논리적 예외 중 하나가 바로 ORA-01403: no data found 입니다. 문법적 오류가 없음에도 불구하고 런타임 시점에 데이터를 찾지 못해 프로그램 흐름을 중단시키는 이 에러의 내부 메커니즘과 실무적인 대응 방안을 살펴보겠습니다.


1. 개요 (Overview)

ORA-01403 에러는 PL/SQL 블록 내의 단일 행 조회(Select Into) 문장이 데이터베이스로부터 단 하나의 행도 가져오지 못했을 때 발생합니다.

일반적인 SQL(SELECT 쿼리) 툴에서는 조회 결과가 없으면 단순히 '0건 조회'로 처리되지만, PL/SQL 내부에서 변수에 값을 담는 SELECT INTO 구문이나 명시적 커서가 아닌 방식에서 결과가 없을 경우 오라클은 이를 예외(Exception) 상황으로 간주하고 이 에러를 발생시킵니다.

2. 내부 메커니즘: PL/SQL의 단일 행 조회(Select Into) 처리

PL/SQL은 SQL의 집합적 처리 결과와 절차적 언어의 변수 할당을 결합한 구조를 가집니다.

  1. SELECT INTO의 무결성 전제: PL/SQL에서 SELECT col1 INTO v_var FROM tab WHERE ... 구문을 실행하면, 오라클은 결과 건수가 정확히 1건 반환될 것을 기대합니다.
  2. NO_DATA_FOUND 예외 트리거: 조회 결과가 0건이면 변수에 대입할 값이 존재하지 않으므로, 오라클은 내부적으로 NO_DATA_FOUND 예외(사전 정의된 예외, 영문 에러 코드 ORA-01403)를 발생시킵니다.
  3. 예외 처리 부재 시 중단: 개발자가 이 예외를 잡기 위한 EXCEPTION 블록을 작성해 두지 않았다면, 해당 PL/SQL 프로그램은 즉시 비정상 종료됩니다.

3. 주요 원인 분석

실무 환경에서 ORA-01403 에러가 발생하는 대표적인 시나리오는 다음과 같습니다.

  • 조건에 부합하는 데이터 부재: 검색 조건(WHERE 절)에 맞는 데이터가 실제 테이블에 존재하지 않는데 단일 행 조회를 수행한 경우입니다.
  • 잘못된 파라미터 값 전달: 애플리케이션이나 상위 프로시저에서 넘어온 키 값(예: EMP_ID)이 잘못되었거나 존재하지 않는 값을 참조할 때 발생합니다.
  • 커서(Cursor) 루프 처리 미흡: 여러 건이 조회될 수 있는 쿼리에 명시적 커서를 사용하지 않고 단순 SELECT INTO를 사용했거나, 반대로 건수가 없는 데이터를 다룰 때 발생합니다.

4. 트러블슈팅 및 해결 방안

ORA-01403 에러를 방지하고 안정적인 PL/SQL 코드를 작성하기 위한 베스트 프랙티스입니다.

단계 1: 예외 핸들러(EXCEPTION 블록) 추가

PL/SQL 내부에 NO_DATA_FOUND 예외를 명시적으로 처리하여 프로그램이 중단되는 것을 막고 대체 로직을 수행합니다.

SQL
 
DECLARE
    v_emp_name employees.emp_name%TYPE;
BEGIN
    -- 단일 행 조회 시도
    SELECT emp_name 
    INTO v_emp_name 
    FROM employees 
    WHERE emp_id = 99999; -- 존재하지 않는 사원 번호 가정

EXCEPTION
    WHEN NO_DATA_FOUND THEN
        -- 데이터가 없을 때의 안전한 대체 처리
        v_emp_name := 'Unknown';
        DBMS_OUTPUT.PUT_LINE('조회된 데이터가 없습니다. 기본값으로 대체합니다.');
END;
/

단계 2: 집계 함수(Max, Count 등) 활용 검토

특정 값이 반드시 존재한다는 보장이 없다면, SELECT INTO 대신 MAX() 함수를 사용하거나 집계 쿼리를 사용하여 결과가 없어도 ORA-01403이 발생하지 않도록 유도할 수 있습니다. (MAX는 데이터가 없어도 에러 대신 NULL을 반환합니다.)

SQL
 
-- MAX 함수를 사용하면 데이터가 없을 때 에러 대신 NULL이 반환되어 안전함
SELECT MAX(emp_name) 
INTO v_emp_name 
FROM employees 
WHERE emp_id = 99999;

5. 요약 및 해시태그

ORA-01403 (No Data Found)는 PL/SQL 환경에서 단일 행 조회 시 데이터 부재로 발생하는 대표적인 예외입니다.

철저한 예외 핸들링 구조 설계와 집계 함수 활용을 통해 견고한 데이터베이스 프로그램을 구현할 수 있습니다.

오라클 데이터베이스를 운영하거나 애플리케이션을 연동할 때, 계정 접속 단계에서부터 막히며 가장 빈번하게 마주치는 에러가 있습니다. 바로 ORA-01017: invalid username/password; logon denied 입니다.

이번 포스팅에서는 ORA-01017 에러의 발생 원인부터 오라클의 인증 메커니즘, 그리고 실무에서 마주치는 함정과 해결 전략을 깊이 있게 살펴보겠습니다.

 


1. 개요 (Overview)

ORA-01017 에러는 클라이언트가 데이터베이스에 접속하기 위해 제공한 사용자명(Username) 또는 비밀번호(Password)가 오라클 서버에 등록된 정보와 일치하지 않거나, 계정이 잠겼거나, 인증 방식을 처리하지 못할 때 발생합니다.

단순히 패스워드를 잘못 입력한 경우부터 오라클 11g 이후 도입된 대소문자 구분(Case Sensitivity), 비밀번호 만료, 특수문자 인코딩 문제까지 다양한 원인으로 트리거되는 대표적인 접속 에러입니다.

2. 내부 메커니즘: 오라클의 인증(Authentication) 프로세스

오라클은 사용자가 접속을 시도할 때 다음과 같은 내부 단계를 거쳐 세션을 생성합니다.

  1. 사용자 정보 대조: 사용자가 입력한 계정 정보는 데이터베이스 내부의 시스템 테이블(DBA_USERS 등)에 저장된 암호화된 해시(Password Hash) 값과 비교됩니다.
  2. 패스워드 복잡도 및 대소문자 검증: 오라클 11g 버전부터는 비밀번호의 대소문자를 엄격하게 구분하며(SEC_CASE_SENSITIVE_LOGON 파라미터), 설정된 보안 정책에 따라 유효성을 검사합니다.
  3. 외부 인증 및 패스워드 파일 (Password File): SYSDBA 같은 특권 계정의 경우 운영체제 인증이나 $ORACLE_HOME/dbs/spw$ORACLE_SID.ora 파일 내의 암호 정보를 기반으로 인증을 수행합니다. 이 파일이 손상되었거나 권한이 맞지 않으면 인증이 거부됩니다.

3. 주요 원인 분석

실무 환경에서 ORA-01017 에러가 발생하는 대표적인 시나리오는 다음과 같습니다.

  • 패스워드 오입력 또는 대소문자 혼동: Caps Lock이 켜져 있었거나, 특수문자가 포함된 비밀번호를 클라이언트 툴이나 애플리케이션 설정 파일(예: application.properties)에 잘못 기재한 경우입니다.
  • 특수문자 인코딩 문제 (URL Encoding 등): 비밀번호에 @, #, ! 같은 특수문자가 포함되어 있을 때, JDBC 커넥션 URL이나 설정 파일에서 인코딩 충돌이 발생해 서버로 잘못된 값이 전달되는 경우입니다.
  • 계정 잠김 (Account Lock) 및 만료: 비밀번호 5회 이상 오류로 인해 계정이 잠기거나(ACCOUNT LOCKED), 패스워드 유효기간이 만료된 경우(EXPIRED) 인증 과정에서 이 에러로 이어질 수 있습니다.
  • 클라이언트-서버 간 오라클 클라이언트 버전 불일치: 매우 오래된 오라클 클라이언트 라이브러리를 사용하여 최신 버전(12c 이상)의 보안 강화된 패스워드 해시 알고리즘을 지원하지 못할 때 발생합니다.

4. 트러블슈팅 및 해결 방안

ORA-01017 에러를 해결하기 위해서는 계정 상태를 점검하고 패스워드를 재설정하거나 올바른 접속 정보를 구성해야 합니다.

단계 1: DBA 권한으로 계정 상태 및 잠김 여부 확인

먼저 SYSDBA 권한으로 접속하여 해당 계정이 실제로 존재하며 잠겨있거나 만료되지 않았는지 확인합니다.

SQL
 
-- 계정 상태 및 생성일, 패스워드 만료 여부 확인
SELECT USERNAME, ACCOUNT_STATUS, EXPIRY_DATE, LOCK_DATE 
FROM DBA_USERS 
WHERE USERNAME = 'TARGET_USER';

단계 2: 패스워드 재설정 (Unlock 포함)

만약 패스워드를 정확히 모른다거나 계정이 잠겨 있다면, DBA 권한으로 새롭게 패스워드를 지정하고 계정을 활성화(Unlock)합니다.

SQL
 
-- 패스워드 변경 및 계정 잠금 해제
ALTER USER TARGET_USER IDENTIFIED BY "NewPassword123!" ACCOUNT UNLOCK;

⚠️ 주의사항: 패스워드에 특수문자가 포함되어 있는 경우, SQL 실행 툴(SQL Developer, DBeaver 등)에 따라 쌍따옴표(")로 감싸주어야 문법 오류를 방지할 수 있습니다.

단계 3: 애플리케이션 접속 정보(JDBC URL 등) 점검

애플리케이션(Spring Boot 등)에서 에러가 발생한다면, 설정 파일의 URL 및 자격 증명 정보를 검증합니다. 특수문자가 포함된 경우 URL 인코딩(%40 등)이 필요할 수 있습니다.

5. 요약 및 해시태그

ORA-01017 (Invalid Username/Password)은 단순한 오타부터 복잡한 보안 인증 정책 충돌까지 다양한 원인으로 발생합니다.

계정 상태 점검과 정확한 패스워드 관리를 통해 신속하게 해결할 수 있습니다.

오라클 개발 및 운영 환경에서 또 하나 피할 수 없는 대표적인 에러, 바로 ORA-01722: invalid number (수치 부적합) 에러입니다.

데이터 형 변환(Implicit/Explicit Type Conversion) 과정에서 발생하는 이 에러는 화면에서는 멀쩡해 보이던 쿼리가 특정 데이터나 조건에 부딪히는 순간 갑자기 실패하게 만들어 개발자를 당황스럽게 만듭니다. 내부 메커니즘과 실무 대응 방안을 살펴보겠습니다.


1. 개요 (Overview)

ORA-01722 에러는 문자열(String)을 숫자(Number) 타입으로 자동 또는 수동 변환하려고 시도했으나, 해당 문자열이 숫자로 변환될 수 없는 문자(공백, 특수문자, 알파벳 등)를 포함하고 있을 때 발생합니다.

예를 들어 '1234'라는 문자열은 숫자로 바꿀 수 있지만, '123A'나 빈 공백(''), 혹은 특수문자가 포함된 문자열을 숫자 컬럼과 비교하거나 연산하려고 하면 오라클은 즉시 이 에러를 던집니다.

2. 내부 메커니즘: 오라클의 암시적 형 변환 (Implicit Conversion)

이 에러의 가장 큰 주범은 개발자가 명시적으로 변환 함수(TO_NUMBER)를 쓰지 않았을 때 오라클이 내부적으로 처리하는 암시적 형 변환입니다.

  1. 데이터 타입 우선순위 (Data Type Precedence): 오라클은 비교 연산(=, >, < 등)이나 함수 처리 시 두 데이터의 타입이 다르면 우선순위에 따라 타입을 일치시키려 합니다. 일반적인 경우 NUMBER 타입이 VARCHAR2 타입보다 우선순위가 높습니다.
  2. 비교문의 함정: 만약 NUMBER 타입으로 정의된 컬럼과 특수문자나 빈 문자열이 포함된 VARCHAR2 형태의 변수/조건 값을 비교하면, 오라클은 NUMBER 컬럼에 맞추기 위해 문자열을 숫자로 바꾸려고 시도합니다.
  3. 변환 실패와 에러 발생: 이때 대상 문자열이 순수 숫자가 아니면 형 변환에 실패하면서 ORA-01722 에러가 발생합니다. 특히 데이터베이스에 적재된 수백만 건의 데이터 중 단 한 건이라도 잘못된 포맷이 존재한다면 쿼리가 무작위로 실패하게 됩니다.

3. 주요 원인 분석

실무 환경에서 ORA-01722 에러가 발생하는 대표적인 시나리오는 다음과 같습니다.

  • 숫자 컬럼과 알파벳/특수문자 포함 문자열의 비교: 예를 들어 EMP_ID가 NUMBER 타입인데, 조건절에 WHERE EMP_ID = 'A100' 형태나 빈 문자열('') 처리를 잘못한 경우입니다.
  • 잘못된 TO_NUMBER 함수 사용: 콤마(,)나 통화 기호($, ₩)가 포함된 문자열을 포맷 지정 없이 TO_NUMBER('1,234')로 변환하려 할 때 발생합니다.
  • DECODE 또는 CASE WHEN 문에서의 타입 불일치: 조건 결과값으로 반환되는 데이터 타입들이 서로 달라서 오라클이 내부적으로 형 변환을 시도하다가 실패하는 경우입니다.

4. 트러블슈팅 및 해결 방안

ORA-01722를 해결하기 위해서는 문제의 데이터와 쿼리를 찾아내어 타입을 정확히 일치시켜야 합니다.

단계 1: 문제의 데이터(잘못된 문자열) 찾아내기

만약 테이블 컬럼 데이터 중에 숫자로 변환할 수 없는 값이 숨어 있다면 아래와 같은 방식을 통해 검출할 수 있습니다. (오라클 12c 이상에서는 VALIDATE_CONVERSION 함수를 활용하면 매우 편리합니다.)

SQL
 
-- VALIDATE_CONVERSION 함수를 이용해 숫자로 변환 불가능한 로우 찾기
SELECT * 
FROM target_table 
WHERE VALIDATE_CONVERSION(column_name AS NUMBER) = 0;

단계 2: 명시적 형 변환(Explicit Conversion) 사용 및 쿼리 수정

암시적 형 변환에 의존하지 말고, 데이터 타입을 명확하게 맞춰줍니다. 또한 포맷 문자가 포함된 경우 적절한 형식을 지정합니다.

SQL
 
-- [잘못된 예시]: 숫자 컬럼과 문자열의 직접 비교 (암시적 변환 유발)
SELECT * FROM employees WHERE salary = '1000';

-- [올바른 예시]: 타입을 일치시키거나 명시적 변환 사용
SELECT * FROM employees WHERE TO_CHAR(salary) = '1000';
-- 또는 
SELECT * FROM employees WHERE salary = TO_NUMBER('1000');

 

+ Recent posts