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

ORA-12722
2026년 09월 16일 | DBMS Error 가이드

이 글에서 다루는 내용

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

ORA-12722 regular expression internal error 는?

ORA-12722 에러는 Oracle 데이터베이스에서 정규 표현식(Regular Expression)을 처리하는 내부 엔진에 예기치 않은 오류가 발생했을 때 나타나는 에러입니다. 주로 REGEXP_LIKE, REGEXP_REPLACE, REGEXP_SUBSTR, REGEXP_INSTR, REGEXP_COUNT 등의 정규식 관련 함수에서 잘못된 패턴을 사용하거나, Oracle 내부 정규식 처리 모듈에 버그가 존재할 때 발생합니다. 이 에러는 단순한 문법 오류를 넘어 Oracle의 정규식 처리 엔진 자체가 비정상적인 상태가 되었을 때 반환되므로, 정확한 원인 분석과 체계적인 접근이 필요합니다.


주요 발생 원인

1. 잘못된 정규 표현식 패턴 사용

가장 빈번하게 발생하는 원인으로, 정규 표현식 문법에 맞지 않는 패턴을 함수에 전달할 때 발생합니다. 예를 들어, 닫히지 않은 괄호, 잘못된 수량자(quantifier) 조합, 또는 POSIX 문자 클래스를 잘못 사용하는 경우가 해당됩니다. Oracle의 정규식 엔진은 POSIX ERE(Extended Regular Expression) 표준을 따르기 때문에, 일반 프로그래밍 언어(Python, Java 등)의 Perl 호환 정규식(PCRE) 문법과 다를 수 있으며, 이 차이를 인지하지 못하고 패턴을 그대로 이식할 경우 내부 오류가 발생하기 쉽습니다.

2. Oracle 버전별 정규식 엔진 버그(Bug)

특정 Oracle 버전에서는 정규식 엔진 내부의 알려진 버그(Known Bug)로 인해 ORA-12722가 발생하는 사례가 보고되어 있습니다. 특히 Oracle 10g, 11g 초기 버전에서 복잡한 패턴이나 특수 문자를 포함한 정규식을 처리할 때 내부 메모리 처리 오류로 인해 에러가 발생한 사례가 다수 존재합니다. 이 경우 Oracle 공식 패치(PSU/RU)를 적용하거나 버전을 업그레이드하는 것이 근본적인 해결책이 됩니다.

3. match_parameter 인수의 잘못된 사용

REGEXP_LIKE, REGEXP_REPLACE 등의 함수에서 마지막 인수로 제공하는 match_parameter에 유효하지 않은 값을 전달할 때 발생합니다. 허용되는 값은 'i'(대소문자 구분 없음), 'c'(대소문자 구분), 'n'(.이 개행 문자 포함), 'm'(다중 행 모드), 'x'(확장 모드)이며, 이외의 문자를 혼합하거나 잘못된 조합을 사용할 경우 Oracle 내부 파싱 오류로 이어질 수 있습니다. 또한 동적 SQL을 통해 외부 입력값이 match_parameter로 그대로 전달되는 경우에도 이 문제가 발생할 수 있어, 입력값 검증이 반드시 필요합니다.


해결 방법

원인 1: 잘못된 정규 표현식 패턴 수정

패턴의 문법 오류를 수정합니다. 닫히지 않은 괄호, 잘못된 반복자(repetition operator) 등을 점검하세요.

문제가 있는 코드 예시:

-- 닫히지 않은 괄호로 인한 ORA-12722 발생
SELECT REGEXP_LIKE('Hello World', '(Hello')
FROM DUAL;

-- 잘못된 수량자 조합
SELECT REGEXP_SUBSTR('abc123', '[a-z]{2,1}')
FROM DUAL;

수정된 올바른 코드 예시:

-- 괄호를 올바르게 닫아줌
SELECT CASE WHEN REGEXP_LIKE('Hello World', '(Hello)') THEN 'MATCH' ELSE 'NO MATCH' END AS result
FROM DUAL;

-- 수량자를 올바른 순서로 수정 (최솟값 <= 최댓값)
SELECT REGEXP_SUBSTR('abc123', '[a-z]{1,2}') AS result
FROM DUAL;

-- POSIX 문자 클래스 올바른 사용
SELECT REGEXP_SUBSTR('test123', '[[:alpha:]]+') AS alpha_only
FROM DUAL;

-- 이메일 패턴 검증 (실무 예제)
SELECT email,
       CASE WHEN REGEXP_LIKE(email, '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$')
            THEN '유효한 이메일'
            ELSE '유효하지 않은 이메일'
       END AS validation_result
FROM user_info;

원인 2: Oracle 패치 적용 전 임시 우회 방법

Oracle 버그로 인한 경우, 패치 적용 전까지 동일한 로직을 대체 함수로 구현할 수 있습니다.

-- Oracle 버그로 복잡한 REGEXP가 실패할 경우, LIKE 또는 INSTR로 대체
-- 문제가 되는 정규식 사용 (버그 발생 가능)
SELECT *
FROM orders
WHERE REGEXP_LIKE(order_code, '^[A-Z]{2}[0-9]{6}$');

-- LIKE를 활용한 임시 우회 방법
SELECT *
FROM orders
WHERE order_code LIKE '________'  -- 8자리 패턴
  AND SUBSTR(order_code, 1, 2) = UPPER(SUBSTR(order_code, 1, 2))
  AND REGEXP_LIKE(SUBSTR(order_code, 3, 6), '^[0-9]{6}$');

-- 현재 Oracle 버전 및 패치 레벨 확인
SELECT * FROM v$version;
SELECT * FROM dba_registry_history ORDER BY action_time DESC;

-- 적용된 패치 목록 확인 (DBA 권한 필요)
SELECT patch_id, patch_uid, description, action, action_time
FROM dba_registry_history
WHERE action = 'APPLY'
ORDER BY action_time DESC;

원인 3: match_parameter 올바른 사용

-- 잘못된 match_parameter 사용 예시
SELECT REGEXP_REPLACE('Hello World', 'hello', 'Hi', 1, 0, 'z')  -- 'z'는 유효하지 않음
FROM DUAL;

-- 올바른 match_parameter 사용 예시
-- 'i': 대소문자 구분 없음
SELECT REGEXP_REPLACE('Hello World', 'hello', 'Hi', 1, 0, 'i') AS result
FROM DUAL;

-- 'n': 개행 문자를 . 메타문자로 매칭
SELECT REGEXP_REPLACE('Line1' || CHR(10) || 'Line2', '.+', 'X', 1, 0, 'n') AS result
FROM DUAL;

-- 'm': 다중 행 모드에서 ^과 $ 사용
SELECT REGEXP_COUNT('Line1' || CHR(10) || 'Line2', '^Line', 1, 'm') AS line_count
FROM DUAL;

-- 'ic' 조합: 대소문자 구분 없음 + 개행 포함 (복합 사용)
SELECT REGEXP_SUBSTR('Hello
World', '.+', 1, 1, 'in') AS result
FROM DUAL;

-- 동적 SQL에서 match_parameter 안전하게 검증하는 예제
DECLARE
    v_pattern      VARCHAR2(200) := '[A-Za-z]+';
    v_source       VARCHAR2(200) := 'Hello World 123';
    v_match_param  VARCHAR2(10)  := 'i';
    v_result       VARCHAR2(200);
BEGIN
    -- match_parameter 유효성 검증
    IF REGEXP_LIKE(v_match_param, '^[icnmx]+$') THEN
        -- 안전하게 정규식 실행
        v_result := REGEXP_SUBSTR(v_source, v_pattern, 1, 1, v_match_param);
        DBMS_OUTPUT.PUT_LINE('결과: ' || v_result);
    ELSE
        DBMS_OUTPUT.PUT_LINE('유효하지 않은 match_parameter입니다: ' || v_match_param);
    END IF;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('에러 발생: ' || SQLERRM);
END;
/

예방 방법

1. 정규 표현식 사전 검증 루틴 도입

운영 환경에 정규식 패턴을 배포하기 전에, 개발 또는 QA 환경에서 충분한 테스트를 수행하는 표준 절차를 수립하세요. 아래와 같이 정규식 유효성을 사전에 검증하는 래퍼(Wrapper) 함수를 만들어 활용하면, 잘못된 패턴으로 인한 운영 장애를 사전에 방지할 수 있습니다.

-- 정규식 유효성 검증 래퍼 함수
CREATE OR REPLACE FUNCTION is_valid_regexp(p_pattern IN VARCHAR2)
RETURN VARCHAR2
IS
    v_dummy NUMBER;
BEGIN
    -- 더미 문자열에 패턴을 적용하여 유효성 검사
    SELECT REGEXP_COUNT('test_string_for_validation', p_pattern)
    INTO v_dummy
    FROM DUAL;
    RETURN 'VALID';
EXCEPTION
    WHEN OTHERS THEN
        -- ORA-12722 등 정규식 관련 에러 포착
        RETURN 'INVALID: ' || SQLERRM;
END;
/

-- 사용 예시
SELECT is_valid_regexp('^[A-Z]{2}[0-9]{4}$') AS check1,  -- 유효
       is_valid_regexp('(unclosed')            AS check2,  -- 유효하지 않음
       is_valid_regexp('[[:alpha:]]+')         AS check3   -- 유효
FROM DUAL;

2. Oracle 정기 패치 적용 및 버전 관리 체계 수립

ORA-12722를 포함한 정규식 관련 버그는 Oracle이 정기 패치(PSU: Patch Set Update, RU: Release Update)를 통해 지속적으로 수정하고 있습니다. DBA는 분기별로 Oracle My Support(MOS)에서 해당 데이터베이스 버전과 관련된 정규식 버그 패치를 모니터링하고, 테스트 환경에서 검증 후 운영 환경에 적용하는 프로세스를 정착시켜야 합니다. 또한 신규 시스템 구축 시에는 가능한 최신 안정화 버전을 선택하여 알려진 버그를 사전에 회피하는 것이 좋습니다.


관련 에러

  • ORA-12721: operation cannot be performed when other sessions are active — 정규식 엔진 초기화 중 다른 세션이 활성화된 경우 발생
  • ORA-12723: regular expression too complex — 정규식 패턴이 지나치게 복잡하여 Oracle 엔진이 처리할 수 없을 때 발생하며, ORA-12722와 함께 자주 혼동됨
  • ORA-12725: unmatched parentheses in regular expression — 괄호가 올바르게 닫히지 않은 경우의 명시적 에러로, ORA-12722보다 구체적인 원인을 나타냄
  • ORA-12726: unmatched bracket in regular expression — 대괄호([]) 문자 클래스가 올바르게 닫히지 않았을 때 발생
  • ORA-12728: invalid range in regular expression — 문자 범위(예: [z-a])가 올바르지 않을 때 발생

DBMS 에러 코드 시리즈

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

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

댓글 남기기