Oracle ORA-00913 오류 원인과 해결 방법 완벽 가이드

ORA-00913
2026년 06월 16일 | DBMS Error 가이드

이 글에서 다루는 내용

ORA-00913 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

ORA-00913 too many values 는?

ORA-00913 에러는 SQL 문장에서 제공된 값의 수가 대상 컬럼이나 표현식의 수보다 많을 때 발생하는 오류입니다. 주로 INSERT 문에서 컬럼 목록보다 값 목록이 더 많거나, 서브쿼리가 기대보다 많은 컬럼을 반환할 때 나타납니다. Oracle 옵티마이저가 SQL을 파싱하는 단계에서 감지되므로, 실행 전에 즉시 에러가 반환되는 것이 특징입니다.


주요 발생 원인

  • INSERT 문에서 컬럼 수와 값 수 불일치

가장 흔한 원인으로, INSERT INTO 문 작성 시 컬럼 목록에 명시한 컬럼 개수보다 VALUES 절에 입력한 값의 개수가 더 많을 때 발생합니다. 예를 들어 3개의 컬럼을 지정했는데 4개의 값을 넣으려 하면 Oracle은 즉시 ORA-00913을 발생시킵니다. 테이블 구조 변경 후 INSERT 쿼리를 미처 수정하지 않았을 때 실무에서 자주 목격됩니다.

  • 서브쿼리가 예상보다 많은 컬럼을 반환

WHERE 절 또는 SELECT 절에서 단일 값을 기대하는 위치에 다중 컬럼을 반환하는 서브쿼리를 사용할 때 발생합니다. 예를 들어 WHERE col = (SELECT col1, col2 FROM ...) 처럼 단일 컬럼 비교 연산자에 복수 컬럼 서브쿼리를 사용하면 이 에러가 발생합니다. IN 절이나 EXISTS 절로 변환하거나 서브쿼리의 SELECT 컬럼을 줄여야 합니다.

  • INSERT INTO … SELECT 문에서 컬럼 수 불일치

INSERT INTO table (col1, col2) SELECT col1, col2, col3 FROM other_table 처럼 SELECT 절에서 반환하는 컬럼 수가 INSERT 대상 컬럼 수보다 많을 때 발생합니다. 대량 데이터 이행 작업이나 ETL 파이프라인 작성 시 자주 발생하며, 특히 SELECT 를 사용하다가 원본 테이블에 컬럼이 추가된 경우 예기치 않게 나타납니다. 항상 SELECT 대신 명시적 컬럼 목록을 사용하는 것이 중요합니다.


해결 방법

원인 1 해결: INSERT VALUES 절 컬럼 수 맞추기

에러가 발생하는 잘못된 예시와 수정된 예시를 확인하세요.

-- ❌ 잘못된 예시: 컬럼은 3개인데 값은 4개
INSERT INTO employees (emp_id, emp_name, dept_id)
VALUES (101, 'Hong GilDong', 10, 'Seoul');

-- ✅ 올바른 예시 1: 값의 수를 컬럼 수에 맞춤
INSERT INTO employees (emp_id, emp_name, dept_id)
VALUES (101, 'Hong GilDong', 10);

-- ✅ 올바른 예시 2: 컬럼 목록에 누락된 컬럼을 추가
INSERT INTO employees (emp_id, emp_name, dept_id, location)
VALUES (101, 'Hong GilDong', 10, 'Seoul');

원인 2 해결: 서브쿼리 컬럼 수 조정

-- ❌ 잘못된 예시: 단일 컬럼 비교에 다중 컬럼 서브쿼리 사용
SELECT *
FROM employees
WHERE dept_id = (SELECT dept_id, dept_name FROM departments WHERE location = 'Seoul');

-- ✅ 올바른 예시 1: 서브쿼리를 단일 컬럼만 반환하도록 수정
SELECT *
FROM employees
WHERE dept_id = (SELECT dept_id FROM departments WHERE location = 'Seoul');

-- ✅ 올바른 예시 2: 여러 조건이 필요하다면 IN 또는 EXISTS 사용
SELECT e.*
FROM employees e
WHERE EXISTS (
    SELECT 1
    FROM departments d
    WHERE d.dept_id = e.dept_id
      AND d.location = 'Seoul'
);

-- ✅ 올바른 예시 3: 다중 컬럼 비교가 필요한 경우 ROW 비교 구문 사용
SELECT *
FROM employees
WHERE (dept_id, job_id) IN (SELECT dept_id, job_id FROM departments WHERE location = 'Seoul');

원인 3 해결: INSERT INTO … SELECT 컬럼 수 일치

-- ❌ 잘못된 예시: SELECT 컬럼이 INSERT 대상보다 많음
INSERT INTO emp_backup (emp_id, emp_name, dept_id)
SELECT emp_id, emp_name, dept_id, salary FROM employees;

-- ✅ 올바른 예시 1: SELECT 컬럼 수를 INSERT 컬럼 수에 맞춤
INSERT INTO emp_backup (emp_id, emp_name, dept_id)
SELECT emp_id, emp_name, dept_id FROM employees;

-- ✅ 올바른 예시 2: 모든 컬럼을 이행하려면 대상 테이블 컬럼도 모두 명시
INSERT INTO emp_backup (emp_id, emp_name, dept_id, salary)
SELECT emp_id, emp_name, dept_id, salary FROM employees;

-- ✅ 실무 팁: 이행 전 컬럼 수 검증 쿼리
SELECT COUNT(*) AS source_col_count
FROM all_tab_columns
WHERE table_name = 'EMPLOYEES'
  AND owner = 'HR';

SELECT COUNT(*) AS target_col_count
FROM all_tab_columns
WHERE table_name = 'EMP_BACKUP'
  AND owner = 'HR';

예방 방법

  • 명시적 컬럼 목록 항상 사용하기

INSERT INTO table VALUES (...) 처럼 컬럼 목록을 생략하거나, SELECT * 를 INSERT와 함께 사용하는 것을 개발 표준에서 금지해야 합니다. 테이블 스키마가 변경되더라도 컬럼을 명시적으로 작성하면 에러를 사전에 방지할 수 있습니다. 코드 리뷰 시 해당 패턴을 반드시 체크 포인트로 등록하고, 가능하면 정적 분석 도구(예: PL/SQL Developer, SQL Developer)의 경고 옵션을 활성화하여 자동으로 감지되도록 설정하세요.

  • 배포 전 DML 검증 루틴 도입

운영 환경에 반영 전, 스테이징 또는 개발 환경에서 DML 문장을 반드시 실행하여 검증하는 프로세스를 구축하세요. 특히 테이블 DDL(컬럼 추가/삭제) 변경이 포함된 배포 시에는, 해당 테이블을 참조하는 모든 INSERT, 서브쿼리, 뷰를 사전에 점검하는 체크리스트를 운영하는 것이 중요합니다. ALL_DEPENDENCIES 뷰를 활용하면 특정 테이블에 의존하는 객체를 빠르게 파악할 수 있습니다.


관련 에러

  • ORA-00947: not enough values — ORA-00913의 반대 상황으로, 값의 수가 컬럼 수보다 적을 때 발생합니다. 두 에러는 항상 쌍으로 이해하는 것이 좋습니다.
  • ORA-01427: single-row subquery returns more than one row — 서브쿼리가 단일 값을 반환해야 하는데 여러 행을 반환할 때 발생하며, ORA-00913과 유사한 맥락에서 서브쿼리 작성 실수로 함께 나타납니다.
  • ORA-00913은 컬럼(열) 수의 문제이고, ORA-01427은 행(로우) 수의 문제라는 점에서 명확히 구분됩니다.

DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기