2026년 08월 15일 | DBMS Error 가이드
이 글에서 다루는 내용
2200C 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
2200C invalid use of escape character 는?
PostgreSQL 에러 코드 2200C는 invalid use of escape character로, SQL 문자열 리터럴 또는 LIKE 패턴 내에서 이스케이프 문자가 잘못 사용되었을 때 발생합니다. 주로 LIKE 또는 SIMILAR TO 절에서 백슬래시(\) 또는 사용자 정의 이스케이프 문자가 올바르지 않은 위치에 사용되거나, ESCAPE 키워드 없이 이스케이프 시퀀스를 처리하려 할 때 나타납니다. 이 에러는 PostgreSQL의 표준 SQL 준수 정책이 강화된 버전(9.x 이후)에서 더욱 자주 목격되며, 레거시 코드를 마이그레이션하는 환경에서 특히 빈번하게 발생합니다.
주요 발생 원인
1. LIKE 패턴에서 이스케이프 문자의 잘못된 사용
가장 흔한 원인은 LIKE 절에서 백슬래시(\)를 이스케이프 문자로 사용할 때, PostgreSQL의 standard_conforming_strings 설정과 충돌하는 경우입니다. PostgreSQL 9.1 이후 standard_conforming_strings가 기본값 on으로 변경되면서, 백슬래시를 이스케이프 문자로 인식하지 않게 되었고, 이로 인해 기존 쿼리가 에러를 유발하게 됩니다. 예를 들어, LIKE '100\%'처럼 백슬래시를 이스케이프 문자로 가정하고 작성된 쿼리는 이 설정에서 오작동하거나 에러를 발생시킬 수 있습니다.
2. ESCAPE 절 없이 특수 문자 처리 시도
LIKE 패턴에서 %나 _ 같은 와일드카드 문자를 리터럴로 사용하려 할 때, ESCAPE 키워드를 명시하지 않고 임의의 이스케이프 시퀀스를 사용하면 이 에러가 발생합니다. SQL 표준에서는 이스케이프 문자를 사용하려면 반드시 ESCAPE 절을 명시해야 하며, 이를 생략하면 파서가 해당 문자를 올바르게 해석하지 못합니다. 오래된 MySQL 기반의 쿼리를 PostgreSQL로 이식할 때 이 문제가 자주 등장합니다.
3. E-string(이스케이프 문자열) 리터럴의 혼용 또는 오남용
PostgreSQL에서는 E'...' 형식의 이스케이프 문자열 리터럴을 지원하지만, 이를 일반 문자열 리터럴과 혼용하거나 잘못된 이스케이프 시퀀스(예: \q, \j 등 정의되지 않은 시퀀스)를 포함하면 에러가 발생합니다. 특히 ORM(Object-Relational Mapping) 프레임워크나 동적 SQL 생성 로직에서 문자열을 자동으로 조합할 때, 예상치 못한 이스케이프 시퀀스가 삽입되어 에러를 유발하는 경우가 많습니다.
해결 방법
원인 1 해결: ESCAPE 절을 명시적으로 지정
LIKE 패턴에서 특수 문자를 리터럴로 사용할 때는 반드시 ESCAPE 절을 명시하세요.
-- 잘못된 예: 백슬래시를 이스케이프로 가정하나 ESCAPE 절 없음
SELECT * FROM products WHERE name LIKE '50\%OFF';
-- 올바른 예: ESCAPE 절 명시
SELECT * FROM products WHERE name LIKE '50\%OFF' ESCAPE '\';
-- 더 권장되는 방법: 다른 이스케이프 문자 사용
SELECT * FROM products WHERE name LIKE '50!%OFF' ESCAPE '!';
-- LIKE에서 언더스코어(_)를 리터럴로 처리하는 예
SELECT * FROM users WHERE username LIKE 'user!_name' ESCAPE '!';
원인 2 해결: standard_conforming_strings 설정 확인 및 E-string 활용
현재 설정을 확인하고, 필요에 따라 E-string 리터럴을 활용하세요.
-- 현재 설정 확인
SHOW standard_conforming_strings;
-- standard_conforming_strings = on 환경에서 올바른 방법
-- 방법 1: ESCAPE 절 명시
SELECT * FROM logs WHERE message LIKE '%error\_%' ESCAPE '\';
-- 방법 2: E-string 리터럴 사용 (권장하지 않음, 혼란 야기 가능)
SELECT * FROM logs WHERE message LIKE E'%error\\_%';
-- 방법 3: 이스케이프가 필요 없는 패턴으로 재설계
SELECT * FROM logs WHERE message LIKE '%error[_]%';
-- 위 방법은 SIMILAR TO와 함께 사용
SELECT * FROM logs WHERE message SIMILAR TO '%error[_]%';
원인 3 해결: 잘못된 이스케이프 시퀀스 수정
E-string 내에서 정의되지 않은 이스케이프 시퀀스를 제거하거나 올바른 시퀀스로 교체하세요.
-- 잘못된 예: 정의되지 않은 이스케이프 시퀀스 \q 사용
SELECT E'\q test'; -- 에러 발생 가능
-- 올바른 예: 유효한 이스케이프 시퀀스만 사용
SELECT E'\n test'; -- 줄바꿈
SELECT E'\t test'; -- 탭
SELECT E'\\ test'; -- 백슬래시 리터럴
-- 동적 SQL에서 안전하게 처리하는 방법: quote_literal 함수 활용
DO $$
DECLARE
v_pattern TEXT := '50%OFF';
v_sql TEXT;
BEGIN
-- quote_literal을 사용하여 안전하게 이스케이프 처리
v_sql := 'SELECT * FROM products WHERE name LIKE ' || quote_literal('%' || v_pattern || '%');
EXECUTE v_sql;
END;
$$;
종합 진단 쿼리
에러가 발생한 쿼리를 분석하고 안전하게 변환하는 예시입니다.
-- 문제가 있는 패턴을 찾아내는 쿼리 예시
-- pg_stat_statements 확장이 설치된 경우
SELECT query, calls, mean_exec_time
FROM pg_stat_statements
WHERE query ILIKE '%LIKE%'
AND query ILIKE '%\\%'
ORDER BY calls DESC
LIMIT 20;
-- 안전한 LIKE 패턴 사용을 위한 함수 작성
CREATE OR REPLACE FUNCTION safe_like_pattern(p_input TEXT)
RETURNS TEXT AS $$
BEGIN
-- 특수 문자를 이스케이프 처리
RETURN replace(replace(replace(p_input, '\', '\\'), '%', '\%'), '_', '\_');
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
-- 함수 사용 예시
SELECT * FROM products
WHERE name LIKE '%' || safe_like_pattern('50%OFF') || '%' ESCAPE '\';
예방 방법
1. 항상 ESCAPE 절을 명시적으로 작성하고 팀 코딩 컨벤션에 포함
LIKE 또는 SIMILAR TO를 사용하는 모든 쿼리에서 이스케이프 문자를 사용할 경우, ESCAPE 절을 생략하지 않는 것을 팀 코딩 컨벤션으로 정립하세요. 코드 리뷰 단계에서 LIKE 패턴에 ESCAPE가 빠진 경우를 체크하는 lint 규칙이나 SQL 정적 분석 도구(예: pgFormatter, SQLFluff)를 도입하면 배포 전에 문제를 사전 차단할 수 있습니다.
-- 팀 컨벤션 예시: 이스케이프가 필요한 모든 LIKE에 ESCAPE 명시
-- 나쁜 예
SELECT * FROM docs WHERE title LIKE '%100\%%';
-- 좋은 예
SELECT * FROM docs WHERE title LIKE '%100!%%' ESCAPE '!';
2. 애플리케이션 레벨에서 파라미터 바인딩 및 전처리 함수 사용
동적 쿼리를 생성할 때는 문자열 연결(concatenation) 방식 대신, 파라미터 바인딩(Prepared Statement)과 전용 이스케이프 처리 함수를 사용하세요. 대부분의 PostgreSQL 클라이언트 라이브러리(psycopg2, pg, jdbc 등)는 파라미터 바인딩 시 이스케이프를 자동으로 처리해주므로, 이를 적극 활용하면 2200C 에러를 원천적으로 방지할 수 있습니다.
-- 애플리케이션(Python psycopg2) 예시
-- 나쁜 예: 문자열 직접 연결
# query = f"SELECT * FROM products WHERE name LIKE '%{user_input}%'"
-- 좋은 예: 파라미터 바인딩 + 이스케이프 처리
# from psycopg2 import sql, extensions
# safe_input = user_input.replace('%', r'\%').replace('_', r'\_')
# cursor.execute("SELECT * FROM products WHERE name LIKE %s ESCAPE '\'", (f'%{safe_input}%',))
-- PostgreSQL 내부에서의 안전한 동적 쿼리 예시
CREATE OR REPLACE FUNCTION search_products(p_keyword TEXT)
RETURNS TABLE(id INT, name TEXT) AS $$
DECLARE
v_pattern TEXT;
BEGIN
-- 특수문자 이스케이프 처리
v_pattern := '%' || replace(replace(p_keyword, '!', '!!'), '%', '!%') || '%';
v_pattern := replace(v_pattern, '_', '!_');
RETURN QUERY
SELECT p.id, p.name
FROM products p
WHERE p.name LIKE v_pattern ESCAPE '!';
END;
$$ LANGUAGE plpgsql STABLE;
관련 에러
- 22025 (
invalid_escape_sequence): 이스케이프 문자열(E'...') 내에서 유효하지 않은 이스케이프 시퀀스가 사용될 때 발생하며, 2200C와 밀접하게 연관됩니다.escape_string_warning설정과 함께 자주 등장합니다. - 42601 (
syntax_error): ESCAPE 절의 문법 자체가 잘못되었을 때 발생하며, 이스케이프 문자가 단일 문자가 아닌 경우(예:ESCAPE 'ab') 함께 나타날 수 있습니다. - 22019 (
invalid_escape_character): ESCAPE 절에 지정된 이스케이프 문자 자체가 유효하지 않을 때(예: 멀티바이트 문자를 이스케이프로 지정) 발생하며, 2200C와 유사한 맥락에서 혼동하기 쉽습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.