오라클(Oracle) 데이터베이스(DBMS)는 강력한 기능만큼이나 다양한 에러코드를 가지고 있어 개발자와 DBA들을 당황하게 만들곤 한다. 하지만, 실무에서 발생하는 대부분의 문제는 몇 가지 주요 에러코드로 집중되어 있다. 이번 포스트를 통해 가장 빈번하게 만나게 될 만한 에러코드들을 알아보고, 당황하지 않고 효율적으로 대처해보자.

 

[ORA-00001: 유일성 제약 조건 위반] (#ora-00001)

에러 메시지

ORA-00001: unique constraint (스키마.제약조건명) violated

발생 원인

이 에러는 PK(Primary Key) 또는 유니크 인덱스가 설정된 컬럼에 중복된 값을 입력하려고 할 때 발생한다. 대량의 데이터를 마이그레이션하거나, 여러 사용자가 동시에 작업할 때 자주 마주치는 에러이다.

실제 사례

레거시 시스템의 데이터를 새 오라클 DB로 마이그레이션하던 중 이 에러가 수천 건 발생 하곤 했다. 원인은 기존 시스템에서는 중복 체크가 제대로 되지 않았던 고객 ID가 새 시스템에서는 유니크 제약조건을 가지게 되었기 때문이었다.

해결 방법

I. 중복 데이터 확인하기

-- 중복된 데이터 찾기
SELECT 컬럼명, COUNT(*)
FROM 테이블명
GROUP BY 컬럼명
HAVING COUNT(*) > 1;

II. 중복 데이터 처리하기
– 데이터가 실제로 중복이라면: 불필요한 행 삭제 또는 병합
– 중복처럼 보이지만 다른 데이터라면: 유니크한 값으로 변경

III. 제약조건 확인하기

-- 어떤 제약조건이 위반되었는지 확인
SELECT constraint_name, constraint_type, table_name
FROM user_constraints
WHERE constraint_name = '에러메시지의_제약조건명';

추가 팁

실무에서는 대량 데이터 삽입 전 임시로 제약조건을 비활성화하고, 데이터 정리 후 다시 활성화하는 방법도 자주 사용한다.

-- 제약조건 비활성화
ALTER TABLE 테이블명 DISABLE CONSTRAINT 제약조건명;

-- 데이터 정리 작업 수행
-- ...

-- 제약조건 다시 활성화
ALTER TABLE 테이블명 ENABLE CONSTRAINT 제약조건명;

 

[ORA-00942: 테이블 또는 뷰가 존재하지 않음] (#ora-00942)

에러 메시지

ORA-00942: table or view does not exist

발생 원인

이 에러는 SQL 문에서 참조하는 테이블이나 뷰가 실제로 존재하지 않거나, 현재 접속한 사용자가 해당 객체에 접근 권한이 없을 때 발생한다. 개발 환경과 운영 환경을 오가며 작업할 때 매우 흔하게 발생하는 에러이다.

실제 사례

개발자가 자신의 개발 환경에서 작성한 쿼리를 실 테스트 환경으로 옮겼을 때 이 에러가 발생했었다. 원인은 개발 환경에서는 테이블 이름을 대소문자 구분 없이 사용했는데, 테스트 환경은 대소문자를 구분하도록 설정되어 있었기 때문이었다.

해결 방법

I. 테이블 존재 여부 확인

-- 모든 테이블 목록 확인
SELECT table_name FROM user_tables;

-- 다른 스키마의 테이블 확인
SELECT table_name FROM all_tables WHERE owner = '스키마명';

II. 권한 확인 및 요청

-- 사용자의 권한 확인
SELECT * FROM session_privs;

-- 특정 객체에 대한 권한 확인
SELECT * FROM user_tab_privs WHERE table_name = '테이블명';

III. 정확한 객체 이름 사용하기

-- 대소문자 구분이 문제라면 정확한 이름 확인
SELECT object_name FROM all_objects
WHERE UPPER(object_name) = UPPER('찾고자하는테이블명');

추가 팁

오라클에서는 기본적으로 객체 이름이 대문자로 저장된다. 소문자나 혼합 케이스로 객체를 생성하려면 따옴표를 사용해야 한다. 이런 경우 항상 동일한 케이스와 따옴표를 사용해야 접근이 가능하다.

-- 이렇게 생성하면 대문자 USER_DATA로 저장됨
CREATE TABLE user_data (...);

-- 이렇게 생성하면 정확히 'user_data'로 저장됨
CREATE TABLE "user_data" (...);

 

[ORA-01017: 유저명/패스워드가 부적합] (#ora-01017)

에러 메시지

ORA-01017: invalid username/password; logon denied

발생 원인

말 그대로 사용자 인증에 실패했을 때 발생하는 에러다. 비밀번호를 잘못 입력하거나, 계정이 잠겨있거나, 만료되었을 때 주로 발생한다. 특히 비밀번호 정책이 강화된 기업 환경에서 자주 만나게 되는 에러이다.

실제 사례

비밀번호 만료 정책에 따라 모든 DB사용자 계정의 비밀번호가 일시적으로 만료되어 전체 계정을 리셋해야 했던 아찔한 경험이 있다.

해결 방법

I. 기본 확인사항
– 사용자 이름과 비밀번호가 정확한지 확인
– Caps Lock이 켜져 있는지 확인
– Oracle 서버에 접속 가능한지 확인

II. 계정 상태 확인 (DBA 권한 필요)

-- 계정 상태 확인
SELECT username, account_status, lock_date, expiry_date
FROM dba_users
WHERE username = 'UPPER(사용자명)';

III. 계정 잠금 해제 (DBA 권한 필요)

-- 계정 잠금 해제
ALTER USER 사용자명 ACCOUNT UNLOCK;

-- 비밀번호 리셋
ALTER USER 사용자명 IDENTIFIED BY 새비밀번호;

추가 팁

비밀번호 만료 정책을 확인하고, 중요하지 않은 개발 환경에서는 비밀번호 만료 기간을 연장하는 것이 좋다.

-- 비밀번호 만료 기간 설정 (180일)
ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME 180;

-- 만료 없이 설정
ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;

 

[ORA-01400: NULL 값을 삽입할 수 없음] (#ora-01400)

에러 메시지

ORA-01400: cannot insert NULL into (스키마.테이블.컬럼)

발생 원인

NOT NULL 제약조건이 설정된 컬럼에 NULL 값을 삽입하려고 할 때 발생한다. 자주 발생하는 원인은:
I. INSERT 문에서 필수 컬럼을 누락
II. UPDATE 문에서 필수 컬럼을 NULL로 설정
III. 애플리케이션에서 빈 문자열(”)을 NULL로 변환

실제 사례

전자상거래 시스템에서 주문 데이터를 입력하는 화면에서 배송지 주소’ 컬럼이 필수 항목으로 변경되었는데, 레거시 시스템에서는 이 필드가 선택사항이었던 것이 문제여서 코드가 DB 제약조건을 적절히 반영하지 못했던 적이 있었다.

해결 방법

I. 테이블 구조 확인

-- 컬럼과 NULL 여부 확인
SELECT column_name, nullable
FROM user_tab_columns
WHERE table_name = '테이블명';

II. 제약조건 확인

-- NOT NULL 제약조건 확인
SELECT constraint_name, column_name
FROM user_cons_columns ucc
JOIN user_constraints uc ON ucc.constraint_name = uc.constraint_name
WHERE uc.constraint_type = 'C'
AND uc.table_name = '테이블명';

III. 데이터 처리 방법
– 필수 데이터가 누락된 경우: 유효한 데이터 추가
– 기본값 설정이 필요한 경우: DEFAULT 값 설정

ALTER TABLE 테이블명 MODIFY 컬럼명 DEFAULT '기본값';

추가 팁

NULL과 빈 문자열(”)은 오라클에서 다르게 처리된다는 점을 기억하자. 일부 DB에서는 빈 문자열을 NULL로 변환하지만, Oracle은 그렇지 않다. 애플리케이션 로직에서 이 부분을 고려해야 한다.

-- NULL과 빈 문자열 비교
SELECT
CASE WHEN NULL = '' THEN 'EQUAL' ELSE 'NOT EQUAL' END AS result
FROM dual;
-- 결과: NOT EQUAL

 

[ORA-01722: 수치가 부적합함] (#ora-01722)

에러 메시지

ORA-01722: invalid number

발생 원인

숫자 데이터 타입의 컬럼에 숫자가 아닌 값을 저장하려고 할 때, 또는 문자열을 숫자로 변환하는 과정에서 문자열이 유효한 숫자 형식이 아닐 때 발생한다. 특히 다양한 소스에서 데이터를 가져와 처리할 때 자주 발생하는 에러이다.

실제 사례

외부 시스템에서 엑셀 파일로 받은 데이터를 임포트하는 과정에서 이 에러가 발생하는 경우가 있었다. 원인은 엑셀에서 숫자 형식으로 보이는 셀이 실제로는 텍스트로 저장되어 있었고, 여기에 숫자가 아닌 문자(예: ‘1,000’)가 포함되어 있었기 때문이었다.

해결 방법

I. 문제가 되는 데이터 찾기

-- 숫자로 변환할 수 없는 데이터 찾기
SELECT * FROM 테이블명
WHERE NOT REGEXP_LIKE(컬럼명, '^[+-]?\d*\.?\d+$');

II. 데이터 정제하기

-- 쉼표와 통화 기호 제거
UPDATE 테이블명
SET 컬럼명 = REGEXP_REPLACE(컬럼명, '[,$₩]', '')
WHERE 조건;

III. 안전한 변환 처리

-- TO_NUMBER 함수 대신 CASE 사용
SELECT
CASE
WHEN REGEXP_LIKE(컬럼명, '^[+-]?\d*\.?\d+$')
THEN TO_NUMBER(컬럼명)
ELSE NULL
END AS 숫자컬럼
FROM 테이블명;

추가 팁

데이터 로딩 전에 외부 데이터의 품질을 검증하는 단계를 추가하는 것이 좋다. 특히 ETL 작업에서는 변환 전 데이터 유효성 검사가 필수적이다.

-- 외부 데이터 검증을 위한 임시 테이블 활용
CREATE TABLE temp_validation AS
SELECT
컬럼1,
컬럼2,
CASE WHEN REGEXP_LIKE(숫자컬럼, '^[+-]?\d*\.?\d+$') THEN 'VALID' ELSE 'INVALID' END AS validation_status
FROM external_table;

 

[ORA-04031: 공유 메모리 할당 불가] (#ora-04031)

에러 메시지

ORA-04031: unable to allocate x bytes of shared memory

발생 원인

오라클 SGA(System Global Area)의 공유 메모리 영역, 특히 공유 풀이나 라지 풀에 할당할 메모리가 부족할 때 발생한다. 동시 사용자가 많거나, 복잡한 쿼리가 많이 실행될 때, 또는 메모리 누수가 있을 때 발생할 수 있다.

실제 사례

월말 보고서 생성 기간에 시스템이 갑자기 느려지면서 이 에러가 발생 한 적이 있는데, 평소보다 3배 이상 많은 사용자가 동시에 복잡한 보고서를 생성하면서 공유 풀 메모리가 부족해진 것이 원인이었다.

해결 방법

I. 현재 메모리 사용량 확인

-- 공유 풀 사용량 확인
SELECT * FROM v$sgastat WHERE pool = 'shared pool' ORDER BY bytes DESC;

-- 라지 풀 사용량 확인
SELECT * FROM v$sgastat WHERE pool = 'large pool' ORDER BY bytes DESC;

II. 단기 해결책: 공유 풀 플러시

-- 공유 풀 플러시 (DBA 권한 필요)
ALTER SYSTEM FLUSH SHARED_POOL;

III. 장기 해결책: 메모리 파라미터 조정

-- 공유 풀 사이즈 증가 (DBA 권한 필요)
ALTER SYSTEM SET shared_pool_size = 512M SCOPE=BOTH;

-- 또는 자동 메모리 관리 사용
ALTER SYSTEM SET memory_target = 4G SCOPE=SPFILE;

추가 팁

메모리 파라미터를 변경하기 전에 AWR(Automatic Workload Repository) 보고서를 분석하여 실제 병목 지점을 찾는 것이 중요하다. 단순히 메모리를 늘리는 것보다 비효율적인 SQL을 튜닝하는 것이 더 효과적일 수 있다.

-- 최근 AWR 스냅샷 확인
SELECT snap_id, begin_interval_time, end_interval_time
FROM dba_hist_snapshot
ORDER BY snap_id DESC
FETCH FIRST 10 ROWS ONLY;

-- AWR 보고서 생성을 위한 스냅샷 ID 확인 후
-- DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT 실행

 

[ORA-12154: TNS 연결 식별자 분석 실패] (#ora-12154)

에러 메시지

ORA-12154: TNS:could not resolve the connect identifier specified

발생 원인

클라이언트가 오라클 데이터베이스에 연결할 때 지정한 TNS 이름을 해석할 수 없을 때 발생한다. 주요 원인은:
I. tnsnames.ora 파일에 지정된 TNS 이름이 없음
II. tnsnames.ora 파일 경로가 잘못됨
III. TNS_ADMIN 환경 변수가 올바르게 설정되지 않음
IV. 네트워크 설정 문제

해결 방법

I. TNS 설정 확인하기

# Windows에서 TNS_ADMIN 환경 변수 확인
echo %TNS_ADMIN%

# Linux/Unix에서 확인
echo $TNS_ADMIN

II. tnsnames.ora 파일 내용 확인
– 연결하려는 서비스 이름이 파일에 정의되어 있는지 확인
– 서비스 이름의 대소문자가 일치하는지 확인
– 문법 오류가 없는지 확인

III. SQL*Net 테스트

# tnsping으로 연결 테스트
tnsping 서비스명

추가 팁

여러 오라클 클라이언트 버전이 설치된 환경에서는 어떤 버전의 tnsnames.ora 파일이 사용되는지 혼란스러울 수 있다. 이런 경우 절대 경로로 TNS_ADMIN을 지정하는 것이 안전하다.

# 명시적 TNS_ADMIN 설정
# Windows
SET TNS_ADMIN=C:\oracle\network\admin

# Linux
export TNS_ADMIN=/opt/oracle/network/admin

또한 EZConnect 방식을 사용하면 tnsnames.ora 없이도 연결할 수 있다:

sqlplus username/password@hostname:port/service_name

 

[ORA-00600: 내부 오류 코드] (#ora-00600)

에러 메시지

ORA-00600: internal error code, arguments: [코드], [인수1], [인수2], ...

발생 원인

ORA-00600은 오라클 내부에서 발생한 오류로, 대개 오라클 소프트웨어의 버그나 심각한 시스템 문제를 나타낸다. 인수로 제공되는 코드는 Oracle 지원팀이 문제를 진단하는 데 사용된다.

실제 사례

한번은 대량의 데이터를 처리하는 배치 작업 중 갑자기 ORA-00600 에러가 발생했다. DB 벤더와 함께 진단한 결과, 특정 버전의 오라클에 존재하던 인덱스 관련 버그였고, 패치 적용으로 해결할 수 있었다.

해결 방법

I. 에러 세부 정보 확인

-- 알림 로그 파일 위치 확인
SELECT value FROM v$parameter WHERE name = 'background_dump_dest';

II. Oracle 지원 데이터베이스 검색
– My Oracle Support(MOS)에서 에러 코드와 인수로 검색
– 유사한 사례와 패치 정보 확인

III. 임시 해결책
– 문제가 발생한 구체적인 작업 식별
– 가능하면 해당 작업을 우회하거나 대체 방법 사용
– 데이터베이스 재시작이 필요할 수 있음

추가 팁

ORA-00600 에러는 심각한 문제일 수 있으므로, 즉시 로그 파일을 백업하고 Oracle 지원팀에 문의하는 것이 좋다. 문제 해결을 위해 다음 정보를 준비하자:

I. 오라클 버전 및 패치 레벨
II. 에러 발생 시간과 상황
III. alert.log 및 트레이스 파일
IV. 가능하면 에러를 재현하는 단계

-- 오라클 버전 확인
SELECT * FROM v$version;

-- 패치 정보 확인
SELECT * FROM dba_registry_history;

 

[ORA-01555: 스냅샷이 너무 오래됨] (#ora-01555)

에러 메시지

ORA-01555: snapshot too old: rollback segment number N with name "XXXX" too small

발생 원인

긴 트랜잭션 실행 중 읽기 일관성을 유지하기 위한 UNDO 데이터가 더 이상 사용 가능하지 않을 때 발생한다. 주로:
I. UNDO 테이블스페이스가 너무 작음
II. 장시간 실행되는 쿼리
III. 동시에 많은 DML 작업 실행

실제 사례

대규모 데이터 마이그레이션 프로젝트에서 테이블 스캔을 포함한 복잡한 분석 쿼리를 실행하는 동안 이 에러가 발생했었다. 동시에 다른 프로세스에서 많은 데이터를 업데이트하고 있었기 때문에 UNDO 공간이 빠르게 재사용되어 문제가 발생했었던 것으로 보인다.

해결 방법

I. UNDO 설정 확인

-- UNDO 설정 확인
SELECT name, value FROM v$parameter WHERE name LIKE 'undo%';

-- UNDO 테이블스페이스 크기 확인
SELECT tablespace_name, sum(bytes)/1024/1024 MB
FROM dba_data_files
WHERE tablespace_name LIKE 'UNDO%'
GROUP BY tablespace_name;

II. UNDO 보존 기간 증가

-- UNDO 보존 기간 설정 (초 단위)
ALTER SYSTEM SET undo_retention = 10800 SCOPE=BOTH; -- 3시간

III. 쿼리 최적화
– 대용량 테이블 전체 스캔 피하기
– 쿼리를 더 작은 배치로 나누기
– 필요한 컬럼만 선택하기

추가 팁

운영 환경에서는 특히 보고서 생성이나 데이터 마이그레이션 같은 대규모 작업을 계획할 때 UNDO 공간을 미리 계획하는 것이 중요하다. 주요 배치 작업이 실행될 예정이라면 임시로 UNDO 보존 기간을 늘리는 것이 좋다.

-- UNDO 사용량 모니터링
SELECT TO_CHAR(begin_time, 'MM/DD/YYYY HH24:MI') begin_time,
TO_CHAR(end_time, 'MM/DD/YYYY HH24:MI') end_time,
maxquerylen, maxconcurrency
FROM v$undostat
ORDER BY begin_time DESC;

 

[ORA-04063: 패키지 내 오브젝트에 오류 발생] (#ora-04063)

에러 메시지

ORA-04063: package body "스키마.패키지명" has errors

발생 원인

패키지, 함수, 프로시저 등의 PL/SQL 객체를 컴파일하거나 실행할 때 오류가 있는 경우 발생한다. 일반적인 원인:
I. 참조하는 객체(테이블, 뷰 등)가 변경됨
II. 참조하는 객체에 대한 권한이 없음
III. 패키지 본문의 코드에 문법 오류
IV. 참조하는 다른 패키지에 오류가 있음

실제 사례

테이블 구조를 변경한 후 관련 패키지가 무효화되어 이 에러가 발생했다. 특히 자주 변경되는 개발 환경에서는 의존성 관리가 제대로 되지 않으면 자주 만나게 되는 문제이다.

해결 방법

I. 오류 세부 정보 확인

-- 객체의 오류 확인
SELECT * FROM user_errors
WHERE name = '패키지명'
ORDER BY sequence;

II. 의존성 확인

-- 패키지가 의존하는 객체 확인
SELECT * FROM user_dependencies
WHERE name = '패키지명';

III. 패키지 재컴파일

-- 패키지 재컴파일
ALTER PACKAGE 패키지명 COMPILE;

-- 전체 스키마 재컴파일
BEGIN
DBMS_UTILITY.compile_schema(schema => 'SCHEMA_NAME');
END;
/

추가 팁

복잡한 애플리케이션에서는 객체 간의 의존성이 복잡하게 얽혀 있을 수 있다. 정확한 컴파일 순서를 보장하려면 utlrp.sql을 사용하여 모든 무효 객체를 재컴파일하는 것이 좋다.

-- 무효 객체 확인
SELECT object_name, object_type FROM user_objects WHERE status = 'INVALID';

-- 재컴파일 후 다시 확인
@?/rdbms/admin/utlrp.sql

 

지금까지 오라클을 사용하면서 가장 자주 만나게 되는 10가지 에러코드와 그 해결 방법에 대해 알아보았다. 이러한 오류들은 대부분 데이터베이스 운영 과정에서 필연적으로 만나게 되는 것들이다. 에러를 마주했을 때 당황하지 말고, 체계적으로 접근하는 습관을 들여보자.

 

 

댓글 남기기