PostgreSQL 2200B 오류 원인과 해결 방법 완벽 가이드

2200B
2026년 10월 13일 | DBMS Error 가이드

이 글에서 다루는 내용

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

2200B escape character conflict 는?

PostgreSQL 에러 코드 2200B: escape character conflict는 LIKE 또는 SIMILAR TO 연산자를 사용할 때 지정한 이스케이프 문자가 패턴 내에서 충돌을 일으키는 경우 발생합니다. 구체적으로, SQL 표준에 따르면 ESCAPE 절에 지정한 문자가 와일드카드 문자(%, _)와 동일하거나, 이스케이프 문자 자체가 패턴 안에서 모호하게 사용될 때 이 에러가 트리거됩니다. 실무에서는 동적 쿼리를 생성하거나 사용자 입력값을 패턴에 직접 삽입할 때 자주 마주치는 에러입니다.


주요 발생 원인

  • 이스케이프 문자로 와일드카드 문자(% 또는 _)를 지정한 경우

LIKE 패턴에서 %와 _는 특수한 의미를 가진 와일드카드 문자입니다. 이 문자들을 ESCAPE 절의 이스케이프 문자로 지정하면, PostgreSQL은 해당 문자가 와일드카드인지 이스케이프 문자인지 구분할 수 없어 충돌이 발생합니다. 예를 들어 ESCAPE '%'처럼 설정하면 2200B 에러가 즉시 발생합니다.

  • 이스케이프 문자를 두 글자 이상의 문자열로 지정한 경우

SQL 표준과 PostgreSQL 명세에 따르면 ESCAPE 절에는 반드시 단일 문자(single character)만 허용됩니다. 두 글자 이상의 문자열을 이스케이프 문자로 지정하려고 하면 에러가 발생합니다. 동적 쿼리를 문자열 연결(concatenation)로 생성할 때 실수로 여러 문자가 포함되는 경우가 많아 주의가 필요합니다.

  • 애플리케이션 레이어에서 이스케이프 처리 없이 사용자 입력을 패턴에 직접 삽입하는 경우

사용자가 입력한 값에 %, _, 또는 현재 설정된 이스케이프 문자가 포함되어 있을 때, 이를 적절히 처리하지 않고 패턴에 직접 삽입하면 의도치 않은 충돌이 발생할 수 있습니다. 이는 에러뿐만 아니라 SQL 인젝션 취약점으로도 이어질 수 있으므로 반드시 파라미터 바인딩과 이스케이프 처리를 병행해야 합니다.


해결 방법

원인 1 해결: 와일드카드가 아닌 안전한 이스케이프 문자 사용

와일드카드 문자(%, _)를 이스케이프 문자로 지정하지 말고, 일반적으로 사용하지 않는 문자(예: \, !, #)를 이스케이프 문자로 지정하세요.

-- 잘못된 예시: % 를 이스케이프 문자로 사용 -> 2200B 에러 발생
SELECT *
FROM products
WHERE product_code LIKE '50%_off' ESCAPE '%';

-- 올바른 예시: \ 를 이스케이프 문자로 사용
SELECT *
FROM products
WHERE product_code LIKE '50\%_off' ESCAPE '\';

-- 또는 ! 를 이스케이프 문자로 사용 (가독성이 더 좋은 경우)
SELECT *
FROM products
WHERE product_code LIKE '50!%_off' ESCAPE '!';

원인 2 해결: 반드시 단일 문자만 ESCAPE 절에 사용

ESCAPE 절에는 정확히 한 글자만 사용해야 합니다. 동적 쿼리 생성 시 이스케이프 문자가 두 글자 이상이 되지 않도록 검증 로직을 추가하세요.

-- 잘못된 예시: 두 글자 이스케이프 문자 -> 에러 발생
SELECT *
FROM employees
WHERE emp_name LIKE 'John!!Smith' ESCAPE '!!';

-- 올바른 예시: 단일 문자 이스케이프
SELECT *
FROM employees
WHERE emp_name LIKE 'John!_Smith' ESCAPE '!';

-- 실무 예시: 동적 검색에서 안전하게 이스케이프 처리
-- PostgreSQL 함수로 이스케이프 처리 캡슐화
CREATE OR REPLACE FUNCTION escape_like_pattern(p_input TEXT, p_escape_char TEXT DEFAULT '!')
RETURNS TEXT AS $$
BEGIN
    -- 이스케이프 문자 자체를 먼저 이스케이프 처리
    RETURN replace(
        replace(
            replace(p_input, p_escape_char, p_escape_char || p_escape_char),
            '%', p_escape_char || '%'
        ),
        '_', p_escape_char || '_'
    );
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT;

-- 함수 사용 예시
SELECT *
FROM products
WHERE product_name LIKE '%' || escape_like_pattern('50% off', '!') || '%' ESCAPE '!';

원인 3 해결: 파라미터 바인딩과 이스케이프 함수 조합 사용

사용자 입력을 패턴에 삽입할 때는 반드시 위에서 만든 이스케이프 함수를 사용하고, 애플리케이션에서는 파라미터 바인딩을 적용하세요.

-- 안전한 검색 쿼리 예시 (사용자 입력: user_input 변수)
-- 애플리케이션에서 파라미터로 전달하는 패턴
PREPARE safe_search (TEXT) AS
SELECT
    product_id,
    product_name,
    price
FROM products
WHERE product_name LIKE '%' || escape_like_pattern($1, '!') || '%' ESCAPE '!'
ORDER BY product_name;

-- 실행 예시
EXECUTE safe_search('50% off');
EXECUTE safe_search('size_L');

-- SIMILAR TO 사용 시 이스케이프 처리 예시
SELECT *
FROM logs
WHERE log_message SIMILAR TO '%(error|warn)!_%' ESCAPE '!';

-- 정규식(POSIX)으로 대체하는 방법 (이스케이프 충돌 완전 회피)
SELECT *
FROM products
WHERE product_name ~ '50\% off';

예방 방법

  • 이스케이프 처리 함수를 공통 유틸리티로 표준화하기

프로젝트 전체에서 LIKE 패턴을 사용하는 모든 쿼리에 대해 위와 같은 이스케이프 처리 함수를 공통 스키마(예: util 스키마)에 등록하고, 코드 리뷰 시 해당 함수 사용 여부를 체크리스트에 포함시키세요. 이렇게 하면 개발자가 개별적으로 이스케이프 처리를 구현하다가 발생하는 실수를 원천 차단할 수 있습니다.

  • LIKE 대신 전문 검색 기능(pg_trgm, to_tsvector) 또는 정규식 활용 검토

복잡한 패턴 검색이 필요하다면 LIKE의 이스케이프 문제를 원천적으로 피하기 위해 PostgreSQL의 전문 검색(Full-Text Search) 기능이나 pg_trgm 확장, 또는 POSIX 정규식(~, ~*)을 사용하는 것을 검토하세요. 이 방법들은 이스케이프 충돌 문제가 없으며 대용량 데이터에서 인덱스 활용이 가능하여 성능도 우수합니다.


관련 에러

  • 22025: invalid_escape_sequence — 이스케이프 시퀀스 자체가 잘못 구성된 경우 발생하며, 2200B와 함께 자주 발생하는 에러입니다. 이스케이프 문자 뒤에 올 수 없는 문자가 오는 경우 트리거됩니다.
  • 2201B: invalid_regular_expression — SIMILAR TO나 POSIX 정규식에서 정규식 문법이 잘못된 경우 발생합니다. LIKE 대신 정규식으로 전환 시 주의가 필요합니다.
  • 42601: syntax_error — 이스케이프 문자를 빈 문자열('')로 지정하거나 SQL 구문 자체가 잘못된 경우 발생합니다.
DBMS 에러 코드 시리즈

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

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

댓글 남기기