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

ORA-00901
2026년 06월 14일 | DBMS Error 가이드

이 글에서 다루는 내용

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

ORA-00901 invalid CREATE command 는?

ORA-00901 에러는 Oracle 데이터베이스에서 CREATE 문을 실행할 때 문법이 올바르지 않거나, Oracle이 인식할 수 없는 형태의 명령어를 사용했을 때 발생하는 에러입니다. 즉, CREATE 키워드 다음에 오는 객체 유형(TABLE, VIEW, INDEX, PROCEDURE 등)이 잘못되었거나, 전체 DDL 구문 자체가 Oracle SQL 파서가 해석할 수 없는 형태일 때 트리거됩니다. 이 에러는 주로 오탈자, 지원되지 않는 구문 사용, 또는 다른 DBMS(MySQL, PostgreSQL 등)에서 작성된 SQL을 Oracle 환경으로 그대로 이식할 때 자주 목격됩니다.


주요 발생 원인

1. CREATE 구문에서 객체 유형 오타 또는 잘못된 키워드 사용

가장 흔한 원인은 단순 오타 혹은 Oracle에서 지원하지 않는 객체 유형 키워드를 사용하는 경우입니다. 예를 들어 CREATE TABEL 처럼 오타가 발생하거나, Oracle이 지원하지 않는 CREATE DATABASE(Standard Edition에서 제한적 지원) 혹은 완전히 잘못된 키워드를 입력하면 즉시 이 에러가 발생합니다. 개발 환경에서 자동 완성 없이 수작업으로 DDL을 작성할 때 특히 자주 발생하므로, 작성 후 반드시 키워드 철자를 검토해야 합니다.

2. 다른 DBMS SQL 구문을 그대로 Oracle에서 실행

MySQL, PostgreSQL, SQL Server 등 다른 RDBMS에서 사용하는 DDL 문법은 Oracle과 상당히 다릅니다. 예를 들어 MySQL의 CREATE TABLE ... ENGINE=InnoDB 구문이나 PostgreSQL의 CREATE SEQUENCE ... AS INTEGER 구문은 Oracle에서 지원되지 않거나 문법이 달라 ORA-00901이 발생할 수 있습니다. 데이터베이스 마이그레이션 프로젝트나 이기종 환경 연동 작업 시 반드시 Oracle 전용 문법으로 변환하는 단계가 필요합니다.

3. OR REPLACE, IF NOT EXISTS 등 미지원 옵션 혼용

Oracle은 CREATE OR REPLACE를 VIEW, PROCEDURE, FUNCTION 등에서만 지원하며, TABLE에는 적용되지 않습니다. 또한 Oracle 23c 이전 버전에서는 CREATE TABLE IF NOT EXISTS 구문을 지원하지 않으므로, 이 구문을 사용하면 ORA-00901이 발생합니다. 버전별로 지원되는 구문이 다르기 때문에, 운영 중인 Oracle 버전에 맞는 공식 문서를 반드시 확인해야 합니다.


해결 방법

원인 1: 오타 및 잘못된 키워드 수정

아래와 같이 잘못된 키워드를 올바르게 수정합니다.

-- 잘못된 예 (오타)
CREATE TABEL employees (
    emp_id   NUMBER(10),
    emp_name VARCHAR2(100)
);
-- ORA-00901: invalid CREATE command 발생

-- 올바른 예
CREATE TABLE employees (
    emp_id   NUMBER(10)    NOT NULL,
    emp_name VARCHAR2(100) NOT NULL,
    hire_date DATE         DEFAULT SYSDATE,
    CONSTRAINT pk_employees PRIMARY KEY (emp_id)
);

객체 유형 키워드는 Oracle 공식 문서 기준으로 다음과 같이 사용합니다.

-- 지원되는 CREATE 객체 유형 예시
CREATE TABLE    ...   -- 테이블 생성
CREATE VIEW     ...   -- 뷰 생성
CREATE INDEX    ...   -- 인덱스 생성
CREATE SEQUENCE ...   -- 시퀀스 생성
CREATE SYNONYM  ...   -- 시노님 생성
CREATE PROCEDURE ...  -- 프로시저 생성
CREATE FUNCTION  ...  -- 함수 생성
CREATE TRIGGER   ...  -- 트리거 생성
CREATE TYPE      ...  -- 타입 생성

원인 2: 타 DBMS 구문을 Oracle 문법으로 변환

-- MySQL 구문 (Oracle에서 ORA-00901 발생)
CREATE TABLE orders (
    order_id   INT AUTO_INCREMENT PRIMARY KEY,
    order_date DATETIME DEFAULT NOW()
) ENGINE=InnoDB;

-- Oracle 전용 문법으로 변환
CREATE SEQUENCE seq_orders START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE;

CREATE TABLE orders (
    order_id   NUMBER(10)  DEFAULT seq_orders.NEXTVAL NOT NULL,
    order_date TIMESTAMP   DEFAULT SYSTIMESTAMP,
    CONSTRAINT pk_orders PRIMARY KEY (order_id)
);
-- PostgreSQL 구문 (Oracle에서 오류 발생 가능)
CREATE SEQUENCE emp_seq AS INTEGER START 1;

-- Oracle 전용 문법
CREATE SEQUENCE emp_seq
    START WITH 1
    INCREMENT BY 1
    MAXVALUE 9999999999
    NOCYCLE
    CACHE 20;

원인 3: OR REPLACE 및 IF NOT EXISTS 구문 처리

-- TABLE에 OR REPLACE 사용 시 오류 (Oracle 미지원)
CREATE OR REPLACE TABLE departments (  -- ORA-00901 발생
    dept_id   NUMBER(5),
    dept_name VARCHAR2(50)
);

-- 올바른 방법: 먼저 DROP 후 CREATE 또는 존재 여부 확인
DECLARE
    v_count NUMBER;
BEGIN
    SELECT COUNT(*) INTO v_count
    FROM user_tables
    WHERE table_name = 'DEPARTMENTS';

    IF v_count > 0 THEN
        EXECUTE IMMEDIATE 'DROP TABLE departments CASCADE CONSTRAINTS';
    END IF;

    EXECUTE IMMEDIATE '
        CREATE TABLE departments (
            dept_id   NUMBER(5)    NOT NULL,
            dept_name VARCHAR2(50) NOT NULL,
            CONSTRAINT pk_departments PRIMARY KEY (dept_id)
        )
    ';

    DBMS_OUTPUT.PUT_LINE(''departments 테이블이 생성되었습니다.'');
END;
/
-- Oracle 23c 이전에서 IF NOT EXISTS 미지원
-- 잘못된 예 (Oracle 21c 이하)
CREATE TABLE IF NOT EXISTS employees ( -- ORA-00901 발생
    emp_id NUMBER PRIMARY KEY
);

-- Oracle 23c 이상에서는 정식 지원
CREATE TABLE IF NOT EXISTS employees (
    emp_id   NUMBER       NOT NULL,
    emp_name VARCHAR2(50) NOT NULL,
    CONSTRAINT pk_emp PRIMARY KEY (emp_id)
);

-- Oracle 21c 이하에서는 PL/SQL로 우회 처리
BEGIN
    EXECUTE IMMEDIATE '
        CREATE TABLE employees (
            emp_id   NUMBER       NOT NULL,
            emp_name VARCHAR2(50) NOT NULL,
            CONSTRAINT pk_emp PRIMARY KEY (emp_id)
        )
    ';
EXCEPTION
    WHEN OTHERS THEN
        IF SQLCODE = -955 THEN  -- ORA-00955: 이미 존재하는 객체명
            DBMS_OUTPUT.PUT_LINE('테이블이 이미 존재합니다. 건너뜁니다.');
        ELSE
            RAISE;
        END IF;
END;
/

예방 방법

1. DDL 스크립트 작성 전 Oracle 버전 및 지원 구문 확인 습관화

운영 중인 Oracle 버전을 SELECT * FROM V$VERSION; 으로 반드시 확인하고, 해당 버전의 공식 Oracle SQL Language Reference 문서를 참조하여 지원되는 CREATE 문법 범위를 사전에 파악해야 합니다. 특히 팀 내에서 여러 Oracle 버전을 혼용하거나, 마이그레이션 프로젝트를 진행 중일 때는 버전별 차이를 문서화하여 공유하는 것이 중요합니다. SQL Developer, Toad 등 Oracle 전용 IDE의 문법 검사(Syntax Check) 기능을 적극 활용하면 실행 전에 오류를 사전 차단할 수 있습니다.

2. DDL 스크립트에 실행 전 검증 루틴 포함 및 코드 리뷰 프로세스 도입

대규모 DDL 배포 시에는 실제 운영 DB에 적용하기 전, 반드시 개발 또는 스테이징 환경에서 먼저 테스트하는 프로세스를 수립해야 합니다. 또한 아래와 같이 스크립트 상단에 버전 확인 및 환경 검증 루틴을 추가하면, 잘못된 환경에서 스크립트가 실행되는 것을 방지할 수 있습니다.

-- DDL 스크립트 상단에 버전 확인 루틴 추가 예시
SET SERVEROUTPUT ON SIZE UNLIMITED;

DECLARE
    v_version  VARCHAR2(100);
    v_major    NUMBER;
BEGIN
    SELECT version INTO v_version FROM v$instance;
    v_major := TO_NUMBER(SUBSTR(v_version, 1, INSTR(v_version, '.') - 1));

    DBMS_OUTPUT.PUT_LINE('현재 Oracle 버전: ' || v_version);

    IF v_major < 12 THEN
        RAISE_APPLICATION_ERROR(-20001,
            'Oracle 12c 이상 버전에서만 실행 가능합니다. 현재 버전: ' || v_version);
    END IF;

    DBMS_OUTPUT.PUT_LINE('버전 검증 완료. DDL 스크립트를 실행합니다.');
END;
/

관련 에러

  • ORA-00900: invalid SQL statement — SQL 문 전체가 Oracle이 인식할 수 없는 형태일 때 발생하며, ORA-00901과 유사하게 문법 오류 계열에 속합니다.
  • ORA-00902: invalid datatype — CREATE TABLE 구문에서 지원되지 않는 데이터 타입을 사용했을 때 발생합니다.
  • ORA-00903: invalid table name — 테이블 이름이 Oracle 명명 규칙에 위배될 때 발생합니다.
  • ORA-00955: name is already used by an existing object — 이미 존재하는 객체와 동일한 이름으로 CREATE를 시도할 때 발생하며, IF NOT EXISTS 우회 처리 시 함께 핸들링해야 합니다.
  • ORA-01031: insufficient privileges — CREATE 권한이 없을 때 발생하며, 객체 생성 실패 시 함께 확인해야 할 에러입니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기