PostgreSQL 2200D 오류: 원인과 해결책 완전 가이드
PostgreSQL 오류 2200D: 잘못된 이스케이프 옥텟
2200D: invalid escape octet 오류는 bytea 값에 잘못된 이스케이프 시퀀스가 포함되어 있을 때 PostgreSQL에서 발생합니다. 이는 주로 바이너리 데이터에 대한 레거시 escape 형식에서 옥텟 값을 \000부터 \377까지의 세 자리 옥탈 숫자로 표현해야 하는데, 범위를 벗어나거나 옥탈이 아닌 숫자를 사용할 경우 즉시 발생합니다.
주요 원인 3가지
-
bytea 이스케이프 리터럴에서 범위를 초과한 옥탈 값
bytea이스케이프 형식은\000부터\377(10진수 0–255)까지의 옥탈 값만 허용합니다.\400과 같은 값이나\9와 같은 옥탈이 아닌 숫자를 사용하면 이 오류가 발생합니다.-- BAD: \400 은 유효한 옥탈 범위를 초과함 (최대는 \377) SELECT E'\\400'::bytea; -- ERROR: invalid escape octet -- BAD: \9 은 유효한 옥탈 숫자가 아님 SELECT E'\\9AB'::bytea; -- ERROR: invalid escape octet -- GOOD: 올바른 옥탈 이스케이프 시퀀스 SELECT E'\\377'::bytea; -- 10진수 255 SELECT E'\\101'::bytea; -- 'A' 문자 SELECT E'\\000'::bytea; -- 널 바이트 -
hex 출력 형식과 escape 형식 문자열을 혼용
PostgreSQL 9.0부터 기본
bytea_output은hex로 설정되었습니다.hex형식 출력을 다시escape형식 입력으로 사용하면 잘못된 이스케이프 시퀀스가 생성될 수 있습니다.-- 현재 bytea 출력 형식 확인 SHOW bytea_output; -- GOOD: hex 형식 사용 (새 프로젝트에서는 권장) SELECT '\xDEADBEEF'::bytea; SELECT '\x48656C6C6F'::bytea; -- 'Hello' -- GOOD: encode/decode 를 이용한 안전한 변환 SELECT encode('\xDEADBEEF'::bytea, 'hex'); -- hex 문자열로 출력 SELECT encode('\xDEADBEEF'::bytea, 'base64'); -- base64 문자열로 출력 SELECT decode('deadbeef', 'hex'); -- hex 문자열 → bytea SELECT decode('SGVsbG8=', 'base64'); -- base64 → bytea -
데이터 마이그레이션 또는 수동 SQL 작성 시 잘못된 이스케이프
다른 DB(Oracle, MySQL)에서 바이너리 데이터를 마이그레이션하거나 직접 INSERT 문을 작성할 때 옥탈과 10진수를 혼동하거나,
standard_conforming_strings = on인 경우 필요한E''접두사를 빼먹는 경우가 많습니다.-- standard_conforming_strings 설정 확인 SHOW standard_conforming_strings; -- BAD: standard_conforming_strings = on 일 때 E'' 접두사 누락 SELECT '\\101'::bytea; -- 이스케이프가 아니라 리터럴 백슬래시로 처리됨 -- GOOD: 이스케이프 시퀀스를 위한 명시적 E'' 접두사 SELECT E'\\101'::bytea; -- 옥탈 이스케이프가 올바르게 해석됨 -- BEST: 마이그레이션 시 decode() 사용 — 이스케이프 문제 전혀 없음 INSERT INTO my_table (data) VALUES (decode('89504e470d0a1a0a', 'hex')); -- PNG 헤더 INSERT INTO my_table (data) VALUES (decode('SGVsbG8gV29ybGQ=', 'base64')); -- 'Hello World'
빠른 해결 방법
-- 데이터베이스 수준에서 hex 를 기본 bytea 출력 형식으로 설정
ALTER DATABASE mydb SET bytea_output = 'hex';
-- hex 문자열을 bytea 로 안전하게 변환하는 헬퍼 함수
CREATE OR REPLACE FUNCTION safe_hex_to_bytea(p_hex TEXT)
RETURNS bytea LANGUAGE plpgsql AS $$
BEGIN
RETURN decode(p_hex, 'hex');
EXCEPTION WHEN OTHERS THEN
RAISE EXCEPTION 'Invalid hex input: %', p_hex;
END;
$$;
-- 안전하게 사용
SELECT safe_hex_to_bytea('deadbeef');
예방 팁
1. bytea 리터럴은 항상 hex 형식을 사용하세요. 팀 표준으로 \x... hex 리터럴 또는 decode()/encode() 함수를 채택하십시오. escape 형식은 오류가 발생하기 쉽고 가독성이 떨어집니다. postgresql.conf 혹은 ALTER DATABASE 로 bytea_output = 'hex' 를 설정합니다.
2. 두 단계 마이그레이션 패턴을 사용하세요. 외부 소스에서 바이너리 데이터를 가져올 때 먼저 TEXT 로 스테이징 테이블에 로드하고 형식을 검증한 뒤, 최종 bytea 컬럼에 변환·삽입합니다. 이렇게 하면 잘못된 이스케이프 시퀀스가 프로덕션에 들어가는 것을 방지할 수 있습니다.
-- 변환 전 hex 형식 검증
SELECT id, raw_data
FROM staging_table
WHERE raw_data !~ '^[0-9a-fA-F]*$'; -- 비 hex 행 찾기
-- 검증 후 안전한 대량 변환
INSERT INTO final_table (id, data)
SELECT id, decode(raw_data, 'hex')
FROM staging_table
WHERE raw_data ~ '^[0-9a-fA-F]+$';
관련 오류
- 22P03
invalid_binary_representation— 바이너리 데이터가 타입의 구조적 규칙을 위반했을 때 발생합니다. 이스케이프 구문 오류와는 별개입니다. - 22021
character_not_in_repertoire— 문자 인코딩 변환 중 발생하며, bytea/text 변환 문제와 함께 나타나는 경우가 많습니다. - 22000
data_exception—2200D및 기타 데이터 형식 오류의 상위 클래스이며, PL/pgSQL 에서는WHEN data_exception으로 넓게 잡을 수 있습니다.
📖 더 자세한 가이드를 원하신다면?
전체 심층 버전(한국어)은 oraerror.com에서 확인하세요 — 상세 분석, 추가 SQL 예제, 예방 팁이 포함되어 있습니다.