2026년 07월 31일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-01758 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-01758 table must be empty to add mandatory (NOT NULL) column 는?
ORA-01758 에러는 데이터가 이미 존재하는 테이블에 NOT NULL 제약조건이 있는 컬럼을 직접 추가하려 할 때 발생하는 Oracle 오류입니다. Oracle은 기존 행(row)에 새로운 NOT NULL 컬럼을 추가하면 해당 행들의 값이 NULL이 되어 제약조건을 위반하게 되므로, 이를 사전에 방지하기 위해 이 에러를 발생시킵니다. 즉, NOT NULL 컬럼을 추가하려면 테이블이 완전히 비어 있거나, DEFAULT 값을 함께 지정해야 정상적으로 처리할 수 있습니다.
주요 발생 원인
1. 데이터가 존재하는 테이블에 DEFAULT 없이 NOT NULL 컬럼 추가 시도
가장 흔한 원인입니다. 운영 중인 테이블에 신규 필수 컬럼을 추가할 때, DEFAULT 값 지정 없이 NOT NULL 제약조건만 명시하면 기존 레코드들의 해당 컬럼 값이 NULL이 되어 제약조건 위반이 발생합니다. 특히 대용량 운영 테이블에서 자주 발생하며, 개발 환경과 운영 환경 간의 절차 차이를 간과했을 때 나타납니다.
2. DDL 스크립트를 개발 환경에서 운영 환경으로 그대로 이관할 때
개발 환경에서는 테이블이 비어 있거나 소량의 테스트 데이터만 존재하여 NOT NULL 컬럼 추가가 아무 문제 없이 실행됩니다. 그러나 동일한 스크립트를 수백만 건의 데이터가 있는 운영 환경에 적용하면 ORA-01758이 발생합니다. 이 경우 DBA가 운영 환경의 데이터 존재 여부를 사전에 확인하지 않은 것이 근본 원인입니다.
3. ORM(Object-Relational Mapping) 프레임워크의 자동 마이그레이션 사용
Hibernate, JPA, Django ORM 등의 프레임워크가 엔티티(Entity) 변경을 감지하여 자동으로 ALTER TABLE 구문을 실행할 때 발생합니다. 프레임워크는 단순히 NOT NULL 컬럼을 추가하는 DDL을 생성하지만, 실제 운영 테이블에는 데이터가 존재하므로 에러가 발생합니다. 자동 스키마 업데이트(auto-ddl, migrate) 기능을 운영 환경에서 활성화하는 것 자체가 위험한 관행입니다.
해결 방법
방법 1: DEFAULT 값을 함께 지정하여 NOT NULL 컬럼 추가 (권장)
Oracle 11g 이상에서는 DEFAULT 값과 NOT NULL 제약조건을 함께 지정하면, Oracle이 내부적으로 최적화하여 기존 데이터를 물리적으로 업데이트하지 않고도 컬럼을 추가할 수 있습니다.
-- 권장 방법: DEFAULT 값과 NOT NULL을 함께 지정
ALTER TABLE employees
ADD (status VARCHAR2(10) DEFAULT 'ACTIVE' NOT NULL);
-- 추가 후 확인
SELECT column_name, data_type, nullable, data_default
FROM user_tab_columns
WHERE table_name = 'EMPLOYEES'
AND column_name = 'STATUS';
방법 2: 3단계 절차를 통한 안전한 컬럼 추가 (Oracle 10g 이하 또는 호환 필요 시)
NULL 허용으로 먼저 컬럼을 추가하고, 기존 데이터를 업데이트한 후, NOT NULL 제약조건을 별도로 추가하는 방식입니다.
-- 1단계: NULL 허용으로 컬럼 추가
ALTER TABLE employees
ADD (department_code VARCHAR2(10));
-- 2단계: 기존 데이터에 기본값 업데이트
UPDATE employees
SET department_code = 'GENERAL'
WHERE department_code IS NULL;
COMMIT;
-- 3단계: NOT NULL 제약조건 추가
ALTER TABLE employees
MODIFY (department_code VARCHAR2(10) NOT NULL);
-- 최종 확인
SELECT COUNT(*) AS null_count
FROM employees
WHERE department_code IS NULL;
방법 3: 테이블 데이터 백업 후 재구성 (테이블 재설계가 필요한 경우)
테이블 구조 자체를 변경해야 하는 경우, 데이터를 임시 테이블에 보관 후 재구성합니다.
-- 1단계: 기존 데이터 백업
CREATE TABLE employees_backup AS
SELECT * FROM employees;
-- 2단계: 기존 테이블 데이터 삭제
TRUNCATE TABLE employees;
-- 3단계: NOT NULL 컬럼 추가 (테이블이 비어있으므로 성공)
ALTER TABLE employees
ADD (mandatory_col VARCHAR2(50) NOT NULL);
-- 4단계: 백업 데이터 복원 (새 컬럼에 적절한 값 부여)
INSERT INTO employees
SELECT e.*, 'DEFAULT_VALUE' AS mandatory_col
FROM employees_backup e;
COMMIT;
-- 5단계: 데이터 정합성 확인 후 백업 테이블 삭제
SELECT COUNT(*) FROM employees;
SELECT COUNT(*) FROM employees_backup;
-- 이상 없을 경우 백업 테이블 삭제
DROP TABLE employees_backup PURGE;
방법 4: 컬럼 추가 전 데이터 존재 여부 사전 확인 스크립트
-- 테이블에 데이터가 있는지 사전 확인
DECLARE
v_count NUMBER;
v_table_name VARCHAR2(30) := 'EMPLOYEES';
BEGIN
SELECT COUNT(*)
INTO v_count
FROM user_tables
WHERE table_name = UPPER(v_table_name);
IF v_count = 0 THEN
DBMS_OUTPUT.PUT_LINE('테이블이 존재하지 않습니다.');
RETURN;
END IF;
EXECUTE IMMEDIATE
'SELECT COUNT(*) FROM ' || v_table_name
INTO v_count;
IF v_count = 0 THEN
DBMS_OUTPUT.PUT_LINE('테이블이 비어있습니다. NOT NULL 컬럼 추가 가능합니다.');
ELSE
DBMS_OUTPUT.PUT_LINE('테이블에 ' || v_count || '건의 데이터가 존재합니다.');
DBMS_OUTPUT.PUT_LINE('DEFAULT 값 지정 또는 3단계 절차를 사용하세요.');
END IF;
END;
/
예방 방법
1. DDL 변경 표준 절차 수립 및 준수
모든 NOT NULL 컬럼 추가 시에는 반드시 DEFAULT 값을 함께 명시하는 것을 팀 내 코딩 표준으로 정의합니다. 또한 운영 환경에 적용하기 전 반드시 스테이징(Staging) 환경에서 운영 데이터와 동일한 규모로 테스트를 수행하고, 변경 이력을 Flyway, Liquibase 등의 데이터베이스 마이그레이션 툴로 관리하는 체계를 갖추는 것이 중요합니다.
-- 나쁜 예 (운영 환경에서 ORA-01758 유발 가능)
ALTER TABLE orders ADD (approval_flag CHAR(1) NOT NULL);
-- 좋은 예 (DEFAULT 값 명시로 안전하게 처리)
ALTER TABLE orders ADD (approval_flag CHAR(1) DEFAULT 'N' NOT NULL);
2. 운영 환경 DDL 적용 전 사전 검증 체크리스트 운영
DDL 배포 전 아래와 같은 체크리스트를 반드시 확인하는 프로세스를 수립합니다. 대상 테이블의 레코드 수 확인, NOT NULL 컬럼 여부 확인, DEFAULT 값 지정 여부 확인, 롤백 계획 수립 등을 포함한 체계적인 검토 절차가 필요합니다.
-- 배포 전 체크리스트 쿼리 예시
SELECT
t.table_name,
t.num_rows,
t.last_analyzed,
c.column_name,
c.nullable,
c.data_default
FROM user_tables t
JOIN user_tab_columns c ON t.table_name = c.table_name
WHERE t.table_name = 'EMPLOYEES'
ORDER BY c.column_id;
관련 에러
- ORA-01735: 잘못된 ALTER TABLE 옵션 지정 시 발생하며, DDL 문법 오류와 함께 나타날 수 있습니다.
- ORA-02296: NOT NULL 제약조건 활성화(ENABLE) 시 이미 존재하는 NULL 값이 있을 때 발생합니다. ORA-01758과 유사한 맥락에서 발생하며, 3단계 절차에서 UPDATE를 누락했을 때 자주 마주칩니다.
- ORA-01407: NOT NULL 컬럼에 NULL 값을 UPDATE하려 할 때 발생하며, 제약조건 추가 이후 데이터 처리 시 주의해야 합니다.
- ORA-00600: 내부 에러로, 드물지만 대용량 테이블에서 DDL 작업 중 발생할 수 있으며 Oracle SR(Service Request)이 필요합니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.