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

ORA-01424
2026년 07월 13일 | DBMS Error 가이드

이 글에서 다루는 내용

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

ORA-01424 missing or illegal character following the escape character 는?

ORA-01424 에러는 SQL 쿼리에서 LIKE 절과 함께 ESCAPE 옵션을 사용할 때, 이스케이프 문자 뒤에 오는 문자가 없거나 허용되지 않는 문자가 위치할 경우 발생하는 오류입니다. Oracle은 LIKE 패턴 매칭에서 와일드카드 문자(%, _)를 리터럴 문자로 처리하기 위해 이스케이프 문자를 지원하는데, 이 이스케이프 문자의 사용 규칙을 위반했을 때 이 에러가 트리거됩니다. 주로 동적 SQL을 생성하는 애플리케이션이나 사용자 입력값을 그대로 쿼리에 삽입하는 경우에 자주 마주치는 에러입니다.


주요 발생 원인

1. ESCAPE 문자 뒤에 아무 문자도 오지 않는 경우 (문자열이 이스케이프 문자로 끝나는 경우)

가장 흔한 원인으로, 검색 패턴 문자열이 이스케이프 문자로 끝날 때 발생합니다. 예를 들어 사용자가 검색어로 '50\'와 같이 역슬래시로 끝나는 문자열을 입력하고, 이를 그대로 LIKE 절에 사용하면 Oracle은 이스케이프 문자 뒤에 처리할 문자가 없어 에러를 발생시킵니다. 이는 사용자 입력을 검증하거나 이스케이프 처리 없이 동적 SQL에 삽입할 때 특히 위험합니다.

2. 이스케이프 문자 뒤에 와일드카드(%, _)나 이스케이프 문자 자신 이외의 문자가 오는 경우

ESCAPE 절로 지정한 문자 뒤에는 반드시 %, _, 또는 이스케이프 문자 자신만 올 수 있습니다. 그 외의 문자가 이스케이프 문자 뒤에 오면 Oracle은 이를 불법적인(illegal) 조합으로 간주하여 ORA-01424를 발생시킵니다. 예를 들어 ESCAPE '\'를 선언했는데 패턴 내에 \a, \b 같은 조합이 포함되어 있으면 에러가 발생합니다.

3. 동적 SQL 또는 애플리케이션에서 사용자 입력값을 검증 없이 삽입하는 경우

Java, Python, PL/SQL 등의 애플리케이션에서 사용자가 입력한 검색어를 별도의 이스케이프 처리 없이 SQL 문자열에 직접 연결(concatenate)할 때 발생합니다. 사용자가 %, _, \ 등의 특수문자를 포함한 검색어를 입력하면 의도치 않게 이스케이프 규칙을 위반하게 되어 에러가 발생하며, 이는 보안 취약점(SQL Injection)으로도 이어질 수 있는 위험한 패턴입니다.


해결 방법

원인 1 해결: 이스케이프 문자로 끝나는 문자열 처리

패턴 문자열에서 이스케이프 문자가 단독으로 끝에 오지 않도록 입력값을 전처리해야 합니다.

-- 문제가 되는 쿼리 (패턴이 \로 끝날 경우 ORA-01424 발생)
SELECT *
FROM   products
WHERE  product_name LIKE '50\' ESCAPE '\';

-- 해결: 이스케이프 문자 자체를 이중으로 처리
-- 입력값의 \ 를 \\ 로 치환한 후 사용
SELECT *
FROM   products
WHERE  product_name LIKE '50\\' ESCAPE '\';

-- PL/SQL에서 동적으로 처리하는 예
DECLARE
    v_search_input VARCHAR2(100) := '50\';  -- 사용자 입력값
    v_pattern      VARCHAR2(200);
    v_count        NUMBER;
BEGIN
    -- 이스케이프 문자(\)를 먼저 이중화한 후, %, _ 처리
    v_pattern := REPLACE(v_search_input, '\', '\\');
    v_pattern := REPLACE(v_pattern,      '%', '\%');
    v_pattern := REPLACE(v_pattern,      '_', '\_');
    v_pattern := v_pattern || '%';  -- 전방 일치 검색

    SELECT COUNT(*)
    INTO   v_count
    FROM   products
    WHERE  product_name LIKE v_pattern ESCAPE '\';

    DBMS_OUTPUT.PUT_LINE('검색 결과 건수: ' || v_count);
END;
/

원인 2 해결: 허용되지 않는 이스케이프 조합 수정

이스케이프 문자 뒤에는 반드시 %, _, 또는 이스케이프 문자 자신만 와야 합니다.

-- 잘못된 사용 예 (ORA-01424 발생)
-- \a, \b 등은 허용되지 않는 조합
SELECT *
FROM   employees
WHERE  last_name LIKE 'O\Brien' ESCAPE '\';
-- 위 쿼리는 \B가 불법 조합이므로 에러 발생

-- 해결 방법 1: 이스케이프가 필요 없는 경우 ESCAPE 절 제거
SELECT *
FROM   employees
WHERE  last_name LIKE 'O''Brien';  -- 작은따옴표는 두 번 반복으로 처리
-- 또는
SELECT *
FROM   employees
WHERE  last_name = 'O''Brien';  -- 정확한 일치라면 = 사용 권장

-- 해결 방법 2: 다른 이스케이프 문자 사용
-- 패턴에 포함된 특수문자와 충돌하지 않는 문자를 ESCAPE로 지정
SELECT *
FROM   employees
WHERE  last_name LIKE '100!%_data' ESCAPE '!';
-- !% 는 리터럴 %, !_ 는 리터럴 _ 를 의미

-- 올바른 ESCAPE 사용 예시 정리
SELECT *
FROM   sales_data
WHERE  discount_code LIKE '10\%OFF' ESCAPE '\'  -- 리터럴 % 검색
UNION ALL
SELECT *
FROM   sales_data
WHERE  column_ref LIKE 'col\_1' ESCAPE '\'       -- 리터럴 _ 검색
UNION ALL
SELECT *
FROM   sales_data
WHERE  path_name LIKE 'C:\\Users\\%' ESCAPE '\'; -- 리터럴 \ 검색

원인 3 해결: 동적 SQL에서 안전한 이스케이프 처리 함수 구현

-- 재사용 가능한 이스케이프 처리 함수 생성
CREATE OR REPLACE FUNCTION escape_like_pattern(
    p_input     IN VARCHAR2,
    p_escape    IN VARCHAR2 DEFAULT '\'
) RETURN VARCHAR2
IS
    v_result VARCHAR2(4000);
BEGIN
    IF p_input IS NULL THEN
        RETURN NULL;
    END IF;

    -- 순서 중요: 이스케이프 문자 자신을 가장 먼저 처리
    v_result := REPLACE(p_input, p_escape, p_escape || p_escape);
    -- 와일드카드 문자 처리
    v_result := REPLACE(v_result, '%', p_escape || '%');
    v_result := REPLACE(v_result, '_', p_escape || '_');

    RETURN v_result;
END escape_like_pattern;
/

-- 함수 사용 예
SELECT *
FROM   products
WHERE  product_name LIKE escape_like_pattern('50%_OFF\Sale') || '%'
ESCAPE '\';

-- 결과적으로 아래와 동일하게 동작
-- WHERE product_name LIKE '50\%\_OFF\\Sale%' ESCAPE '\'

-- 동적 SQL에서의 안전한 사용 (Bind Variable 활용 권장)
DECLARE
    v_user_input VARCHAR2(100) := '&search_term';
    v_sql        VARCHAR2(1000);
    v_pattern    VARCHAR2(200);
    TYPE ref_cur IS REF CURSOR;
    v_cursor     ref_cur;
    v_row        products%ROWTYPE;
BEGIN
    v_pattern := escape_like_pattern(v_user_input) || '%';

    -- Bind Variable을 사용한 안전한 동적 SQL
    v_sql := 'SELECT * FROM products WHERE product_name LIKE :1 ESCAPE :2';

    OPEN v_cursor FOR v_sql USING v_pattern, '\';
    LOOP
        FETCH v_cursor INTO v_row;
        EXIT WHEN v_cursor%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE(v_row.product_name);
    END LOOP;
    CLOSE v_cursor;
END;
/

예방 방법

1. 사용자 입력값 처리를 위한 전용 이스케이프 함수 표준화

위에서 작성한 escape_like_pattern과 같은 함수를 공통 유틸리티 패키지에 포함시켜 프로젝트 전체에서 일관되게 사용해야 합니다. LIKE 검색을 사용하는 모든 코드 경로에서 사용자 입력이 반드시 이 함수를 거치도록 코드 리뷰 기준을 수립하고, 가능하다면 애플리케이션 레이어(Java, Python 등)에서도 동일한 전처리 로직을 적용하는 것이 이중 방어 측면에서 유리합니다.

2. Bind Variable 사용 의무화 및 동적 SQL 최소화

사용자 입력을 SQL 문자열에 직접 연결(concatenation)하는 방식을 절대적으로 지양하고, 반드시 Bind Variable(바인드 변수)을 사용해야 합니다. 이는 ORA-01424를 포함한 다양한 SQL 에러를 예방할 뿐 아니라 SQL Injection 보안 취약점을 근본적으로 차단하고, 실행 계획 공유(Cursor Sharing)를 통한 성능 향상까지 얻을 수 있는 Best Practice입니다. 동적 SQL이 반드시 필요한 경우에도 DBMS_SQL 패키지나 EXECUTE IMMEDIATE ... USING 구문을 통해 바인드 변수를 적극 활용하십시오.


관련 에러

  • ORA-01425: ESCAPE 절에 지정한 이스케이프 문자가 단일 문자(1바이트)가 아닌 경우 발생합니다. ESCAPE 뒤에는 반드시 길이가 1인 문자 리터럴만 올 수 있습니다.
  • ORA-01426: 수치 오버플로우와 관련된 에러로, 문자열 처리 중 발생할 수 있으나 ORA-01424와는 직접적인 연관은 낮습니다.
  • ORA-00907: LIKE 절의 문법 오류로 인해 발생하는 괄호 누락 에러로, 이스케이프 처리 실수와 함께 동반될 수 있습니다.
  • ORA-01722: 이스케이프 처리 오류로 인해 데이터 타입 변환이 실패할 경우 연쇄적으로 발생할 수 있는 “invalid number” 에러입니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기