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

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

이 글에서 다루는 내용

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

ORA-00900 invalid SQL statement 는?

ORA-00900 에러는 Oracle 데이터베이스가 실행하려는 SQL 구문을 유효한 SQL 명령으로 인식하지 못할 때 발생하는 오류입니다. 즉, 파서(Parser)가 입력된 문장을 분석하는 과정에서 문법적으로 올바르지 않거나, 완전히 잘못된 형태의 문장을 만났을 때 이 에러가 발생합니다. 주로 오타, 잘못된 키워드 사용, 지원되지 않는 SQL 구문 사용 등이 원인이 되며, 초보 개발자부터 숙련된 DBA까지 실수로 마주칠 수 있는 에러입니다.


주요 발생 원인

1. SQL 키워드 오타 또는 잘못된 문법 사용

가장 흔한 원인으로, SELECT 대신 SELEC, FROM 대신 FORM 과 같이 SQL 예약 키워드를 잘못 입력하는 경우입니다. 또한 Oracle SQL 문법에 존재하지 않는 키워드나 다른 DBMS(MySQL, MS-SQL 등)의 전용 문법을 그대로 사용할 때도 동일한 에러가 발생합니다. 예를 들어 MySQL의 SHOW TABLES 같은 명령을 Oracle에서 사용하면 ORA-00900이 발생합니다.

2. PL/SQL 블록이나 프로시저에서 SQL문 앞뒤의 구조적 오류

PL/SQL 블록 내에서 BEGIN/END 없이 단독 PL/SQL 문을 실행하거나, 익명 블록의 구조가 불완전할 때 Oracle 파서가 이를 유효하지 않은 SQL로 판단합니다. 특히 애플리케이션에서 동적 SQL을 조합하는 과정에서 문자열 연결 오류로 인해 앞부분 키워드가 잘려나가거나 빈 문자열이 SQL로 전달되는 경우도 자주 발생합니다. 이 경우 실행 전에 완성된 SQL 문자열을 로그로 출력하여 확인하는 습관이 중요합니다.

3. 세미콜론(;) 또는 슬래시(/) 등 불필요한 종결 문자 포함

JDBC, ODBC, OCI 등의 드라이버를 통해 SQL을 실행할 때 문장 끝에 세미콜론(;)을 포함시키면 ORA-00900이 발생하는 경우가 있습니다. SQL*Plus 환경에서는 세미콜론이 허용되지만, 프로그래밍 언어에서 드라이버를 통해 직접 실행할 때는 세미콜론을 제거해야 합니다. 또한 여러 SQL 문을 하나의 실행 호출로 묶어서 보내는 경우에도 이 에러가 발생할 수 있습니다.


해결 방법

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

잘못된 예시와 올바른 예시를 비교하여 키워드 철자와 문법을 점검합니다.

-- 잘못된 SQL (키워드 오타)
SELEC emp_name, salary
FORM employees
WHER department_id = 10;

-- 올바른 SQL
SELECT emp_name, salary
FROM employees
WHERE department_id = 10;

Oracle에서 지원하지 않는 타 DBMS 문법은 Oracle 동등 문법으로 대체해야 합니다.

-- MySQL 전용 문법 (Oracle에서 ORA-00900 발생)
-- SHOW TABLES;
-- DESCRIBE employees;  ← SQL*Plus에서는 가능하나 JDBC에서는 불가

-- Oracle 동등 쿼리
SELECT table_name
FROM user_tables
ORDER BY table_name;

-- 테이블 컬럼 정보 확인
SELECT column_name, data_type, data_length, nullable
FROM user_tab_columns
WHERE table_name = 'EMPLOYEES'
ORDER BY column_id;

원인 2: 동적 SQL 문자열 디버깅

동적 SQL을 구성할 때는 실행 전에 반드시 완성된 쿼리를 출력하여 검증하는 과정을 거쳐야 합니다.

-- 동적 SQL 생성 시 디버깅 예시 (PL/SQL)
DECLARE
    v_sql       VARCHAR2(4000);
    v_table     VARCHAR2(30) := 'EMPLOYEES';
    v_dept_id   NUMBER       := 10;
    v_count     NUMBER;
BEGIN
    -- 동적 SQL 문자열 조합
    v_sql := 'SELECT COUNT(*) FROM ' || v_table
             || ' WHERE department_id = :dept_id';

    -- 실행 전 SQL 확인 (디버깅용)
    DBMS_OUTPUT.PUT_LINE('실행 SQL: ' || v_sql);

    -- 바인드 변수를 사용한 안전한 실행
    EXECUTE IMMEDIATE v_sql INTO v_count USING v_dept_id;

    DBMS_OUTPUT.PUT_LINE('결과 건수: ' || v_count);
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('에러 발생 SQL: ' || v_sql);
        DBMS_OUTPUT.PUT_LINE('에러 메시지: ' || SQLERRM);
        RAISE;
END;
/

빈 문자열이나 NULL이 SQL로 전달되는 것을 방어하는 코드도 추가합니다.

-- NULL 또는 빈 문자열 방어 코드
DECLARE
    v_sql VARCHAR2(4000);
BEGIN
    v_sql := NULL; -- 잘못된 경우 시뮬레이션

    IF v_sql IS NULL OR TRIM(v_sql) IS NULL THEN
        RAISE_APPLICATION_ERROR(-20001, 'SQL 문자열이 비어 있습니다.');
    END IF;

    EXECUTE IMMEDIATE v_sql;
END;
/

원인 3: 세미콜론 및 종결 문자 제거

Java JDBC 환경에서의 올바른 SQL 실행 방법 예시입니다.

-- Oracle JDBC에서 실행 시 잘못된 예 (세미콜론 포함 → ORA-00900 유발 가능)
-- String sql = "SELECT * FROM employees WHERE employee_id = 100;";

-- 올바른 예 (세미콜론 제거)
-- String sql = "SELECT * FROM employees WHERE employee_id = 100";

-- Oracle SQL*Plus 또는 SQL Developer에서는 아래처럼 세미콜론 사용 가능
SELECT employee_id, first_name, last_name, salary
FROM employees
WHERE employee_id = 100;

-- PL/SQL 익명 블록 실행 시 슬래시(/) 필요 (SQL*Plus 기준)
BEGIN
    DBMS_OUTPUT.PUT_LINE('Hello, Oracle!');
END;
/

여러 SQL 문을 하나의 배치로 실행할 때는 각 문장을 개별적으로 실행해야 합니다.

-- 잘못된 방법: 두 개의 SQL을 한 번에 실행 시도
-- SELECT * FROM employees; SELECT * FROM departments;

-- 올바른 방법: 각각 별도 실행
SELECT employee_id, first_name, department_id
FROM employees
WHERE rownum <= 5;

-- 별도 실행
SELECT department_id, department_name
FROM departments
WHERE rownum <= 5;

예방 방법

1. SQL 작성 도구 및 린터(Linter) 활용

Oracle SQL Developer, Toad, DBeaver 같은 전문 SQL IDE를 사용하면 작성 중에 실시간으로 문법 오류를 감지하고 자동 완성 기능을 제공하여 오타로 인한 ORA-00900을 사전에 방지할 수 있습니다. 특히 대규모 애플리케이션 개발 시에는 코드 리뷰 단계에서 SQL 문법 검증 도구를 CI/CD 파이프라인에 통합하는 것을 강력히 권장합니다. 동적 SQL을 많이 사용하는 프로젝트라면 실행 전 SQL 문자열 유효성 검사 로직을 공통 모듈로 만들어 재사용하는 것이 좋습니다.

2. 바인드 변수 사용 및 SQL 실행 전 로깅 습관화

하드코딩된 값 대신 바인드 변수(Bind Variable)를 사용하면 SQL 인젝션 방어뿐 아니라 동적 SQL 조합 오류도 줄일 수 있습니다. 또한 운영 환경에서도 예외 처리 블록 내에 실패한 SQL 문자열을 로그 테이블에 저장하는 습관을 들이면 ORA-00900 발생 시 원인을 신속하게 파악하고 대응할 수 있습니다. 아래는 로그 테이블 활용 예시입니다.

-- SQL 에러 로그 테이블 생성
CREATE TABLE sql_error_log (
    log_id      NUMBER GENERATED ALWAYS AS IDENTITY,
    error_time  TIMESTAMP DEFAULT SYSTIMESTAMP,
    error_code  VARCHAR2(20),
    error_msg   VARCHAR2(4000),
    failed_sql  VARCHAR2(4000),
    created_by  VARCHAR2(100) DEFAULT USER
);

-- 에러 로깅 예시
DECLARE
    v_sql VARCHAR2(4000);
BEGIN
    v_sql := 'SELEC * FORM employees'; -- 오타 포함 SQL
    EXECUTE IMMEDIATE v_sql;
EXCEPTION
    WHEN OTHERS THEN
        INSERT INTO sql_error_log (error_code, error_msg, failed_sql)
        VALUES (SQLCODE, SQLERRM, v_sql);
        COMMIT;
        RAISE;
END;
/

관련 에러

  • ORA-00901: CREATE 명령 뒤에 유효하지 않은 객체 유형이 오는 경우 발생하며, ORA-00900과 유사하게 문법 오류 계열에 속합니다.
  • ORA-00903: 테이블 이름이 유효하지 않을 때 발생하는 에러로, FROM 절에 잘못된 테이블명을 지정했을 때 나타납니다.
  • ORA-00907: 괄호가 누락된 경우 발생하는 에러입니다. 복잡한 서브쿼리나 함수 사용 시 괄호 짝이 맞지 않을 때 자주 발생합니다.
  • ORA-00911: SQL 문장 내에 세미콜론 등 유효하지 않은 문자가 포함되어 있을 때 발생하며, ORA-00900과 함께 자주 혼동됩니다.
  • ORA-00921: SQL 키워드가 예상치 못한 위치에서 끝날 때, 즉 문장이 불완전하게 종료될 때 발생합니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기