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

ORA-12723
2026년 09월 17일 | DBMS Error 가이드

이 글에서 다루는 내용

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

ORA-12723 regular expression compile error 는?

ORA-12723 에러는 Oracle 데이터베이스에서 정규 표현식(Regular Expression)을 처리하는 과정에서 컴파일 오류가 발생했을 때 나타나는 에러입니다. 주로 REGEXP_LIKE, REGEXP_SUBSTR, REGEXP_INSTR, REGEXP_REPLACE, REGEXP_COUNT 등의 정규식 관련 함수 또는 조건절에서 잘못된 패턴 문법이 사용되었을 때 발생합니다. Oracle 내부의 정규 표현식 엔진(POSIX 기반)이 주어진 패턴을 해석하지 못할 경우, SQL 실행이 중단되고 해당 에러가 반환됩니다.


주요 발생 원인

1. 잘못된 정규 표현식 문법 사용

가장 흔한 원인으로, 정규 표현식의 문법 자체가 올바르지 않을 때 발생합니다. 예를 들어 괄호((, ))나 대괄호([, ])의 짝이 맞지 않거나, 수량자(, +, ?)의 위치가 잘못된 경우 Oracle 정규식 컴파일러가 패턴을 해석할 수 없어 에러를 반환합니다. 특히 + 같은 수량자를 아무런 앞선 표현식 없이 사용하거나, 이스케이프 처리가 잘못된 경우 자주 발생합니다.

2. 지원되지 않는 정규 표현식 기능 사용

Oracle의 정규 표현식 엔진은 POSIX ERE(Extended Regular Expression) 표준을 기반으로 하며, Perl이나 Python에서 지원되는 일부 고급 기능(예: 전방 탐색(lookahead), 후방 탐색(lookbehind), 명명된 그룹 등)은 지원하지 않습니다. 다른 언어나 도구에서 정상 동작하던 정규 표현식을 Oracle SQL에 그대로 옮겨 올 때, 지원되지 않는 구문이 포함되어 있으면 컴파일 에러가 발생합니다. Oracle 12c 이후 일부 기능이 추가되었으나, 여전히 지원 범위에 제한이 있으므로 주의가 필요합니다.

3. 특수 문자 이스케이프 미처리

정규 표현식 내에서 ., ^, $, |, \, (, ), [, ], {, } 등의 메타 문자(Meta Character)는 특별한 의미를 가집니다. 이를 리터럴 문자로 사용하고 싶을 때 적절한 이스케이프 처리(\ 또는 [] 내에 포함)를 하지 않으면 Oracle 엔진이 잘못 해석하여 컴파일 에러를 유발합니다. 예를 들어 전화번호 패턴에서 .를 점 기호 그 자체로 쓰려는데 이스케이프를 빠트리는 실수가 실무에서 매우 빈번합니다.


해결 방법

원인 1 해결: 정규 표현식 문법 교정

괄호 짝, 수량자 위치를 반드시 점검하고, 패턴을 단계적으로 단순화하여 테스트하십시오.

-- 잘못된 예: 수량자가 앞선 표현식 없이 사용됨
SELECT REGEXP_SUBSTR('Hello World', '+[A-Z]') FROM DUAL;
-- ORA-12723 발생

-- 올바른 예: 수량자 앞에 적절한 문자 클래스 지정
SELECT REGEXP_SUBSTR('Hello World', '[A-Z]+') FROM DUAL;

-- 잘못된 예: 닫히지 않은 괄호
SELECT REGEXP_LIKE('test123', '(test[0-9') FROM DUAL;
-- ORA-12723 발생

-- 올바른 예: 괄호 닫기 처리
SELECT * FROM DUAL WHERE REGEXP_LIKE('test123', '(test[0-9]+)');

-- 패턴 단계적 검증 방법 (간단한 패턴부터 시작)
SELECT REGEXP_SUBSTR('ORA-12723 Error', '[A-Z]+') FROM DUAL;
SELECT REGEXP_SUBSTR('ORA-12723 Error', '[A-Z]+-[0-9]+') FROM DUAL;
SELECT REGEXP_SUBSTR('ORA-12723 Error', 'ORA-[0-9]{5}') FROM DUAL;

원인 2 해결: 지원되지 않는 기능 대체

Oracle에서 지원하지 않는 전방/후방 탐색 대신 Oracle 호환 문법으로 변환하십시오.

-- Perl 스타일 (Oracle 미지원) - ORA-12723 발생
-- (?<=ORA-)\d+ 와 같은 후방 탐색은 사용 불가

-- Oracle 호환 대체 방법: 서브쿼리 또는 REGEXP_SUBSTR 활용
-- 에러 코드 번호 추출 예제
SELECT REGEXP_SUBSTR('ORA-12723: regular expression compile error', 
                     'ORA-([0-9]+)', 1, 1, NULL, 1) AS error_code
FROM DUAL;

-- 명명된 그룹 대신 번호 기반 캡처 그룹 사용
SELECT REGEXP_SUBSTR('2024-01-15', 
                     '([0-9]{4})-([0-9]{2})-([0-9]{2})', 
                     1, 1, NULL, 1) AS year_part,
       REGEXP_SUBSTR('2024-01-15', 
                     '([0-9]{4})-([0-9]{2})-([0-9]{2})', 
                     1, 1, NULL, 2) AS month_part,
       REGEXP_SUBSTR('2024-01-15', 
                     '([0-9]{4})-([0-9]{2})-([0-9]{2})', 
                     1, 1, NULL, 3) AS day_part
FROM DUAL;

-- 복잡한 조건은 여러 REGEXP 함수 조합으로 대체
SELECT employee_id, last_name
FROM employees
WHERE REGEXP_LIKE(last_name, '^[A-Z]')
  AND REGEXP_LIKE(last_name, '[aeiou]$', 'i');

원인 3 해결: 특수 문자 이스케이프 처리

메타 문자를 리터럴로 사용할 경우 반드시 \로 이스케이프하거나 []로 감싸십시오.

-- 잘못된 예: 점(.)이 메타 문자로 해석되어 의도와 다른 결과
SELECT REGEXP_SUBSTR('192.168.1.1', '192.168.1.1') FROM DUAL;
-- 에러는 아니지만 의도와 다른 패턴 매칭 가능

-- 올바른 예: 점을 리터럴로 이스케이프
SELECT REGEXP_SUBSTR('192.168.1.1', '192\.168\.1\.1') FROM DUAL;

-- 전화번호 패턴에서 하이픈(-) 이스케이프
-- 잘못된 예 (대괄호 내 하이픈 위치 오류)
SELECT * FROM employees 
WHERE REGEXP_LIKE(phone_number, '[0-9-+]');
-- ORA-12723 발생 가능

-- 올바른 예: 하이픈을 대괄호 맨 앞이나 맨 뒤에 위치
SELECT * FROM employees 
WHERE REGEXP_LIKE(phone_number, '[0-9+\-]');

-- 특수 문자 이스케이프 종합 예제
-- 이메일 형식 검증 (실무 패턴)
SELECT email
FROM employees
WHERE REGEXP_LIKE(email, '^[A-Za-z0-9._%+\-]+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}$');

-- 이스케이프 문자 확인을 위한 테스트 쿼리
SELECT 
    CASE WHEN REGEXP_LIKE('test.value', 'test\.value') 
         THEN '점(.) 이스케이프 성공' 
         ELSE '매칭 실패' 
    END AS result
FROM DUAL;

정규식 패턴 디버깅 방법

-- 패턴 유효성을 빠르게 확인하는 방법
-- DUAL 테이블을 활용한 단계적 테스트
BEGIN
  IF REGEXP_LIKE('sample_text_123', '[a-z]+_[a-z]+_[0-9]+') THEN
    DBMS_OUTPUT.PUT_LINE('패턴 유효: 컴파일 성공');
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('에러 발생: ' || SQLERRM);
END;
/

-- 여러 패턴 한 번에 테스트하는 프로시저
CREATE OR REPLACE PROCEDURE test_regex_pattern(
  p_string  IN VARCHAR2,
  p_pattern IN VARCHAR2
) AS
BEGIN
  IF REGEXP_LIKE(p_string, p_pattern) THEN
    DBMS_OUTPUT.PUT_LINE('매칭 성공: [' || p_string || '] ~ /' || p_pattern || '/');
  ELSE
    DBMS_OUTPUT.PUT_LINE('매칭 실패: 패턴이 문자열과 일치하지 않음');
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('ORA-12723 또는 기타 에러: ' || SQLERRM);
END;
/

-- 프로시저 실행 예
EXEC test_regex_pattern('ORA-12723', 'ORA-[0-9]{5}');
EXEC test_regex_pattern('hello@example.com', '^[\w.+-]+@[\w-]+\.[a-z]{2,}$');

예방 방법

1. 정규 표현식 사전 검증 및 단계적 개발

운영 SQL에 정규 표현식 패턴을 바로 적용하지 말고, 반드시 개발/테스트 환경에서 DUAL 테이블을 활용하여 단계적으로 패턴을 검증한 후 적용하십시오. 복잡한 패턴은 가장 단순한 형태부터 시작해서 조건을 하나씩 추가해가며 테스트하는 습관을 들이고, 팀 내 정규 표현식 패턴 라이브러리(공통 검증 패턴 모음)를 관리하여 검증된 패턴을 재사용하는 것을 권장합니다. 또한, Oracle 공식 문서의 정규 표현식 지원 범위를 주기적으로 확인하고, 외부 언어에서 가져온 패턴은 반드시 Oracle 호환성 검토를 거쳐야 합니다.

-- Best Practice: 공통 검증 패턴 뷰 생성 예시
CREATE OR REPLACE VIEW regex_pattern_library AS
SELECT 'EMAIL'       AS pattern_name, 
       '^[A-Za-z0-9._%+\-]+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}$' AS pattern
FROM DUAL
UNION ALL
SELECT 'PHONE_KR',   '^01[0-9]-[0-9]{3,4}-[0-9]{4}$' FROM DUAL
UNION ALL
SELECT 'DATE_YYYYMMDD', '^[0-9]{4}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])$' FROM DUAL
UNION ALL
SELECT 'IP_ADDRESS', '^([0-9]{1,3}\.){3}[0-9]{1,3}$' FROM DUAL;

-- 패턴 라이브러리 활용 예
SELECT p.pattern_name, p.pattern,
       CASE WHEN REGEXP_LIKE('test@example.com', p.pattern) 
            THEN 'VALID' ELSE 'INVALID' END AS test_result
FROM regex_pattern_library p
WHERE p.pattern_name = 'EMAIL';

2. 예외 처리 및 에러 모니터링 체계 구축

정규 표현식이 포함된 PL/SQL 코드에는 반드시 EXCEPTION 블록을 구현하여 ORA-12723 발생 시 적절히 처리하고 로그를 남기십시오. 에러 발생 시 사용자에게는 친절한 메시지를 보여주고, 내부적으로는 에러 로그 테이블에 패턴과 입력값을 함께 기록하여 원인 추적이 가능하도록 구성해야 합니다.

-- 에러 로깅 테이블 생성
CREATE TABLE regex_error_log (
  log_id      NUMBER GENERATED ALWAYS AS IDENTITY,
  log_time    TIMESTAMP DEFAULT SYSTIMESTAMP,
  pattern     VARCHAR2(4000),
  input_value VARCHAR2(4000),
  error_code  NUMBER,
  error_msg   VARCHAR2(4000)
);

-- 안전한 정규식 래퍼 함수 생성
CREATE OR REPLACE FUNCTION safe_regexp_like(
  p_value   IN VARCHAR2,
  p_pattern IN VARCHAR2,
  p_flags   IN VARCHAR2 DEFAULT NULL
) RETURN NUMBER AS
BEGIN
  IF REGEXP_LIKE(p_value, p_pattern, NVL(p_flags, 'c')) THEN
    RETURN 1;
  ELSE
    RETURN 0;
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    INSERT INTO regex_error_log (pattern, input_value, error_code, error_msg)
    VALUES (p_pattern, p_value, SQLCODE, SQLERRM);
    COMMIT;
    RETURN -1; -- 에러 발생 시 -1 반환
END;
/

-- 함수 활용 예
SELECT employee_id, email,
       safe_regexp_like(email, '^[A-Za-z0-9._%+\-]+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}$') AS email_valid
FROM employees;

관련 에러

  • ORA-12725: unmatched parentheses in regular expression – 정규 표현식 내 괄호의 짝이 맞지 않을 때 발생하며, ORA-12723과 함께 자주 나타납니다.
  • ORA-12726: unmatched bracket in regular expression – 대괄호([])가 제대로 닫히지 않은 경우 발생합니다.
  • ORA-12727: invalid back reference in regular expression – 존재하지 않는 캡처 그룹을 역참조할 때 발생합니다.
  • ORA-12728: invalid range in regular expression – 문자 클래스 내 범위 지정이 잘못된 경우 (예: [z-a]) 발생합니다.
  • ORA-12729: invalid character class in regular expression – POSIX 문자 클래스([:alpha:] 등) 사용 오류 시 발생합니다.

이 에러들은 모두 Oracle 정규 표현식 엔진의 컴파일 단계에서 발생하며, 발생 시 반환되는 에러 메시지와 함께 패턴의 어느 부분이 문제인지 확인하는 것이 중요합니다.


DBMS 에러 코드 시리즈

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

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

댓글 남기기