2026년 07월 11일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-01407 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-01407 cannot update to NULL 는?
ORA-01407 에러는 NOT NULL 제약 조건(Constraint)이 설정된 컬럼에 NULL 값을 UPDATE하려 할 때 발생하는 오류입니다. Oracle 데이터베이스는 테이블 정의 시 특정 컬럼에 NOT NULL 제약을 걸어 반드시 유효한 값이 존재하도록 강제하는데, 이를 위반하는 UPDATE 구문이 실행될 경우 해당 에러가 발생합니다. 주로 애플리케이션 로직의 변경, 잘못된 데이터 마이그레이션, 또는 개발자의 실수로 인해 실무 환경에서 빈번하게 발생하는 에러입니다.
주요 발생 원인
1. NOT NULL 제약 조건이 설정된 컬럼에 직접 NULL을 할당하는 경우
가장 일반적인 원인으로, 개발자가 테이블 스키마를 충분히 파악하지 못한 채 UPDATE 구문을 작성할 때 발생합니다. 예를 들어, EMPLOYEE 테이블의 SALARY 컬럼이 NOT NULL로 정의되어 있음에도 불구하고 SET SALARY = NULL과 같은 구문을 실행하면 즉시 ORA-01407이 발생합니다. 특히 ORM(Object-Relational Mapping) 프레임워크를 사용하는 환경에서 자동 생성된 쿼리가 NULL을 전달하는 경우가 많아 주의가 필요합니다.
2. 서브쿼리(Subquery)의 결과값이 NULL을 반환하는 경우
UPDATE 구문에서 SET 절에 서브쿼리를 사용할 때, 해당 서브쿼리가 매칭되는 행을 찾지 못하면 NULL을 반환하게 됩니다. 이 NULL 값이 NOT NULL 제약이 설정된 컬럼에 적용되면 ORA-01407이 발생합니다. 이는 개발 단계에서는 테스트 데이터가 충분히 있어 문제가 없다가, 운영 환경에서 특정 조건의 데이터가 없을 때 갑자기 에러가 발생하는 경우가 많아 디버깅이 까다로운 유형입니다.
3. 데이터 마이그레이션 또는 배치(Batch) 작업 중 NULL 데이터가 포함된 경우
대량 데이터 이관 작업이나 배치 UPDATE 작업 시, 원본 데이터 자체에 NULL이 포함되어 있거나 변환(Transformation) 로직의 오류로 인해 NULL이 생성될 수 있습니다. 수만 건 이상의 데이터를 처리하는 배치 작업에서 이 에러가 발생하면 작업 전체가 롤백되어 큰 운영 장애로 이어질 수 있습니다. 사전에 NULL 여부를 검증하는 로직 없이 배치 작업을 실행하는 것은 매우 위험하며, 반드시 데이터 품질 검증 단계를 선행해야 합니다.
해결 방법
원인 1 해결: 직접 NULL 할당 방지
컬럼의 제약 조건을 먼저 확인한 후, NULL 대신 기본값(Default Value)을 사용하도록 쿼리를 수정합니다.
-- 문제가 되는 쿼리 (ORA-01407 발생)
UPDATE employees
SET salary = NULL
WHERE employee_id = 100;
-- 해결 방법 1: 기본값으로 대체
UPDATE employees
SET salary = 0
WHERE employee_id = 100;
-- 해결 방법 2: 컬럼 제약 조건 먼저 확인
SELECT column_name, nullable, data_default
FROM user_tab_columns
WHERE table_name = 'EMPLOYEES'
AND column_name = 'SALARY';
-- 필요한 경우 NOT NULL 제약을 제거 (운영 환경에서는 신중하게 결정)
ALTER TABLE employees MODIFY (salary NUMBER(10,2) NULL);
원인 2 해결: 서브쿼리의 NULL 반환 방지
NVL 또는 COALESCE 함수를 사용하여 서브쿼리 결과가 NULL일 경우 대체값을 지정합니다.
-- 문제가 되는 쿼리 (서브쿼리가 NULL을 반환할 수 있음)
UPDATE employees e
SET e.department_name = (
SELECT d.department_name
FROM departments d
WHERE d.department_id = e.department_id
);
-- 해결 방법: NVL로 NULL 방어 처리
UPDATE employees e
SET e.department_name = NVL(
(SELECT d.department_name
FROM departments d
WHERE d.department_id = e.department_id),
'미지정' -- NULL 대신 사용할 기본값
);
-- 해결 방법 2: 서브쿼리 결과가 NULL인 행을 WHERE 절로 필터링
UPDATE employees e
SET e.department_name = (
SELECT d.department_name
FROM departments d
WHERE d.department_id = e.department_id
)
WHERE EXISTS (
SELECT 1
FROM departments d
WHERE d.department_id = e.department_id
);
-- 사전 점검: NULL을 반환하는 행 확인
SELECT e.employee_id, e.department_id
FROM employees e
WHERE NOT EXISTS (
SELECT 1
FROM departments d
WHERE d.department_id = e.department_id
);
원인 3 해결: 배치 작업 전 NULL 데이터 사전 검증
배치 UPDATE 실행 전에 반드시 NULL 데이터를 탐지하고 처리하는 로직을 추가합니다.
-- 배치 작업 전 NULL 포함 데이터 사전 점검
SELECT COUNT(*) AS null_count
FROM source_table
WHERE salary IS NULL
OR department_id IS NULL;
-- NULL이 있는 경우 기본값으로 치환 후 업데이트
UPDATE target_table t
SET t.salary = (
SELECT NVL(s.salary, 0) -- NULL이면 0으로 대체
FROM source_table s
WHERE s.employee_id = t.employee_id
)
WHERE t.employee_id IN (
SELECT employee_id FROM source_table
);
-- MERGE 문을 활용한 안전한 대량 업데이트
MERGE INTO target_table t
USING (
SELECT employee_id,
NVL(salary, 0) AS salary,
NVL(department_id, 99) AS department_id
FROM source_table
WHERE salary IS NOT NULL -- NULL 행은 아예 제외
) s
ON (t.employee_id = s.employee_id)
WHEN MATCHED THEN
UPDATE SET
t.salary = s.salary,
t.department_id = s.department_id;
-- 실행 후 영향받은 행 수 확인
SELECT SQL_ID, ROWS_PROCESSED
FROM V$SQL
WHERE SQL_TEXT LIKE '%target_table%'
ORDER BY LAST_ACTIVE_TIME DESC
FETCH FIRST 5 ROWS ONLY;
예방 방법
1. 애플리케이션 레이어와 DB 레이어의 이중 검증 체계 구축
데이터베이스의 NOT NULL 제약 조건만을 최후 방어선으로 삼지 말고, 애플리케이션 코드에서도 NULL 여부를 사전에 검증하는 로직을 반드시 포함시켜야 합니다. 특히 ORM을 사용하는 환경에서는 Entity 클래스의 필드에도 @NotNull 어노테이션 등을 활용하여 입력 단계에서 NULL을 차단하는 것이 좋습니다. DB 레이어에서는 아래와 같이 CHECK 제약이나 트리거를 활용하여 추가 방어 로직을 구성할 수 있습니다.
-- 테이블 제약 조건 전체 현황 정기 점검 쿼리
SELECT table_name, column_name, nullable, data_default
FROM user_tab_columns
WHERE nullable = 'N'
ORDER BY table_name, column_id;
2. 개발/운영 환경 배포 전 DDL 변경 영향도 분석 및 테스트 의무화
테이블 스키마가 변경될 때마다 기존 DML 구문들이 영향을 받는지 반드시 검토해야 합니다. 특히 새로운 NOT NULL 컬럼이 추가되거나, 기존 컬럼의 NULL 허용 여부가 변경될 경우 연관된 모든 UPDATE 구문을 재검토해야 합니다. CI/CD 파이프라인에 DB 단위 테스트를 포함시켜 스키마 변경 시 자동으로 DML 검증이 이루어지도록 체계를 갖추는 것이 장기적으로 가장 효과적인 예방책입니다.
관련 에러
- ORA-01400:
cannot insert NULL into— INSERT 시 NOT NULL 컬럼에 NULL을 삽입하려 할 때 발생하는 에러로, ORA-01407과 유사한 원인에서 비롯되며 함께 자주 등장합니다. - ORA-02290:
check constraint violated— CHECK 제약 조건을 위반할 때 발생하며, NOT NULL 제약 위반과 함께 데이터 무결성 이슈로 묶여서 다루어지는 경우가 많습니다. - ORA-01722:
invalid number— NULL이 아닌 잘못된 타입의 값이 숫자형 컬럼에 들어올 때 발생하며, 데이터 유효성 검증이 부족한 환경에서 ORA-01407과 함께 발생하는 경우가 있습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.