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

2200F
2026년 08월 17일 | DBMS Error 가이드

이 글에서 다루는 내용

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

2200F zero length character string 는?

PostgreSQL 에러 코드 2200F (zero_length_character_string)는 길이가 0인 문자열, 즉 빈 문자열('')이 허용되지 않는 컨텍스트에서 사용될 때 발생하는 에러입니다. 주로 정규 표현식 함수, 특정 문자열 처리 함수, 또는 타입 변환 과정에서 빈 문자열이 입력값으로 전달될 때 이 에러가 트리거됩니다. SQL 표준(SQLSTATE 22)의 데이터 예외 계열에 속하며, 런타임 시 데이터 유효성 검사에 실패했음을 의미합니다.


주요 발생 원인

1. 정규 표현식 함수에 빈 패턴 전달

regexp_replace(), regexp_match(), regexp_split_to_table() 등 PostgreSQL의 정규 표현식 함수는 패턴 인자로 빈 문자열을 허용하지 않습니다. 예를 들어 사용자 입력을 그대로 정규 표현식 패턴으로 전달하는 동적 쿼리에서 입력값이 비어 있으면 즉시 이 에러가 발생합니다. 이 경우는 실무에서 가장 빈번하게 마주치는 원인이며, 특히 검색 기능 구현 시 필터 조건이 비어 있을 때 자주 발생합니다.

-- 에러 발생 예시
SELECT regexp_replace('hello world', '', 'X');
-- ERROR:  invalid regular expression: 2200F zero_length_character_string

SELECT regexp_match('test string', '');
-- ERROR:  invalid regular expression: 2200F zero_length_character_string

2. SIMILAR TO 또는 LIKE 연산자와 빈 패턴의 조합

SIMILAR TO 연산자는 SQL 표준 정규 표현식을 사용하는데, 내부적으로 빈 패턴을 처리하지 못합니다. 동적으로 생성된 WHERE 절에서 패턴 변수가 빈 문자열로 설정되면 예상치 못한 에러가 발생할 수 있습니다. 이 경우는 ORM 프레임워크나 동적 SQL을 생성하는 미들웨어 레이어에서 특히 주의가 필요합니다.

-- 에러 발생 예시 (일부 PostgreSQL 버전 및 컨텍스트)
SELECT 'test' SIMILAR TO '';
-- 빈 패턴으로 인한 예기치 않은 동작 발생 가능

-- 함수 내부에서의 패턴 검증
CREATE OR REPLACE FUNCTION search_users(pattern TEXT)
RETURNS TABLE(username TEXT) AS $$
BEGIN
    -- pattern이 ''인 경우 에러 발생
    RETURN QUERY
    SELECT name FROM users WHERE name ~ pattern;
END;
$$ LANGUAGE plpgsql;

3. 타입 변환 및 캐스팅 과정에서의 빈 문자열

일부 PostgreSQL 타입 변환 함수나 캐스팅 연산에서 빈 문자열이 유효하지 않은 입력으로 간주될 수 있습니다. 예를 들어, 빈 문자열을 특정 도메인 타입이나 커스텀 타입으로 변환하려 할 때 해당 타입의 입력 함수가 이 에러를 발생시킬 수 있습니다. 사용자 정의 도메인에 CHECK 제약 조건이 있는 경우 빈 문자열이 제약 조건을 위반하면서 연쇄적으로 이 에러가 발생하기도 합니다.

-- 커스텀 도메인 예시
CREATE DOMAIN non_empty_text AS TEXT
    CHECK (VALUE <> '' AND VALUE IS NOT NULL);

-- 에러 발생
INSERT INTO employees (name) VALUES (''::non_empty_text);
-- ERROR: value for domain non_empty_text violates check constraint

-- ENUM 또는 특수 타입 변환 시
SELECT ''::xml;
-- 일부 버전에서 zero length 관련 에러 발생 가능

해결 방법

원인 1 해결: 정규 표현식 함수 호출 전 빈 문자열 검사

함수 호출 전에 반드시 패턴이 비어 있지 않은지 확인하고, 빈 문자열인 경우 대안 로직을 적용하세요.

-- NULLIF를 활용한 안전한 처리
SELECT CASE
    WHEN pattern IS NULL OR pattern = '' THEN original_text
    ELSE regexp_replace(original_text, pattern, replacement)
END AS result
FROM (VALUES ('hello world', '', 'X')) AS t(original_text, pattern, replacement);

-- 실무용 안전한 래퍼 함수 작성
CREATE OR REPLACE FUNCTION safe_regexp_replace(
    input_text  TEXT,
    pattern     TEXT,
    replacement TEXT,
    flags       TEXT DEFAULT ''
)
RETURNS TEXT AS $$
BEGIN
    -- 빈 패턴 방어 로직
    IF pattern IS NULL OR length(pattern) = 0 THEN
        RETURN input_text;
    END IF;
    RETURN regexp_replace(input_text, pattern, replacement, flags);
EXCEPTION
    WHEN SQLSTATE '2200F' THEN
        RAISE WARNING 'zero_length_character_string caught for pattern: [%]', pattern;
        RETURN input_text;
END;
$$ LANGUAGE plpgsql IMMUTABLE;

-- 사용 예시
SELECT safe_regexp_replace('hello world', '', 'X');   -- 'hello world' 반환
SELECT safe_regexp_replace('hello world', 'l', 'L');  -- 'heLLo worLd' 반환

원인 2 해결: 동적 패턴 검색 시 조건 분기 처리

-- 동적 검색 함수 개선 버전
CREATE OR REPLACE FUNCTION search_users(pattern TEXT)
RETURNS TABLE(username TEXT) AS $$
BEGIN
    -- 빈 패턴이면 전체 반환
    IF pattern IS NULL OR trim(pattern) = '' THEN
        RETURN QUERY SELECT name FROM users;
        RETURN;
    END IF;

    -- 유효한 패턴인 경우에만 정규식 적용
    RETURN QUERY
    SELECT name FROM users
    WHERE name ~* pattern;

EXCEPTION
    WHEN SQLSTATE '2200F' THEN
        RAISE EXCEPTION 'Invalid search pattern provided: %', pattern;
END;
$$ LANGUAGE plpgsql;

-- COALESCE와 NULLIF 조합으로 인라인 처리
SELECT *
FROM products
WHERE
    (:search_term = '' OR product_name ~* NULLIF(:search_term, ''));

원인 3 해결: 도메인 및 타입 변환 방어 처리

-- 삽입 전 빈 문자열 검증 트리거
CREATE OR REPLACE FUNCTION validate_non_empty_fields()
RETURNS TRIGGER AS $$
BEGIN
    IF NEW.name IS NOT NULL AND length(trim(NEW.name)) = 0 THEN
        RAISE EXCEPTION 'Column "name" must not be an empty string (SQLSTATE 2200F prevention)';
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_validate_employees_name
BEFORE INSERT OR UPDATE ON employees
FOR EACH ROW EXECUTE FUNCTION validate_non_empty_fields();

-- 애플리케이션 레이어에서 데이터 정제 후 삽입
INSERT INTO employees (name)
SELECT NULLIF(trim(input_name), '')  -- 빈 문자열은 NULL로 변환
FROM staging_data
WHERE input_name IS NOT NULL;

예방 방법

1. 입력 유효성 검증 레이어 구축

애플리케이션 레이어와 데이터베이스 레이어 양쪽에서 이중으로 빈 문자열을 검증하는 습관을 들이세요. PostgreSQL의 CHECK 제약 조건과 BEFORE 트리거를 활용하면 잘못된 데이터가 DB에 저장되기 전에 차단할 수 있습니다. 특히 정규 표현식 함수를 사용하는 모든 저장 프로시저에는 반드시 입력값 길이 검증 로직을 포함시켜야 합니다.

-- 테이블 레벨 CHECK 제약 조건 추가
ALTER TABLE users
    ADD CONSTRAINT chk_username_not_empty
    CHECK (username IS NULL OR length(trim(username)) > 0);

-- 공통 검증 함수 라이브러리화
CREATE OR REPLACE FUNCTION is_valid_pattern(p TEXT)
RETURNS BOOLEAN AS $$
    SELECT p IS NOT NULL AND length(trim(p)) > 0;
$$ LANGUAGE sql IMMUTABLE;

2. 예외 처리 블록과 로깅 표준화

운영 환경에서는 SQLSTATE '2200F'를 명시적으로 캐치하는 예외 처리 블록을 모든 정규 표현식 관련 함수에 추가하고, 발생 시 충분한 컨텍스트 정보를 로그에 남겨 빠른 디버깅이 가능하도록 하세요. 중앙화된 에러 로깅 테이블을 운영하면 패턴을 분석하고 근본 원인을 파악하는 데 큰 도움이 됩니다.

-- 중앙 에러 로깅 테이블 및 패턴
CREATE TABLE IF NOT EXISTS db_error_log (
    id          BIGSERIAL PRIMARY KEY,
    error_code  TEXT,
    error_msg   TEXT,
    context     JSONB,
    occurred_at TIMESTAMPTZ DEFAULT now()
);

-- 예외 처리 + 로깅 패턴
CREATE OR REPLACE FUNCTION safe_search(pattern TEXT)
RETURNS SETOF TEXT AS $$
BEGIN
    RETURN QUERY SELECT data FROM my_table WHERE data ~ pattern;
EXCEPTION
    WHEN SQLSTATE '2200F' THEN
        INSERT INTO db_error_log(error_code, error_msg, context)
        VALUES ('2200F', 'zero_length_character_string',
                jsonb_build_object('pattern', pattern, 'function', 'safe_search'));
        RAISE WARNING '2200F error logged for pattern: [%]', pattern;
END;
$$ LANGUAGE plpgsql;

관련 에러

  • 22001 (string_data_right_truncation): 문자열 데이터가 컬럼의 최대 길이를 초과할 때 발생하며, 2200F와 반대 방향의 문자열 길이 관련 에러입니다.
  • 22P02 (invalid_text_representation): 텍스트를 특정 타입으로 변환할 수 없을 때 발생하며, 빈 문자열 캐스팅 문제와 함께 나타나는 경우가 많습니다.
  • 2201B (invalid_regular_expression): 정규 표현식 자체가 문법적으로 잘못되었을 때 발생하며, 2200F와 마찬가지로 regexp 계열 함수에서 주로 발생합니다. 빈 문자열 패턴은 종종 이 두 에러 코드 중 하나로 나타납니다.
  • 23514 (check_violation): 도메인이나 테이블의 CHECK 제약 조건을 위반했을 때 발생하며, 빈 문자열 방어 로직을 CHECK 제약으로 구현한 경우 2200F 대신 이 에러가 반환될 수 있습니다.
DBMS 에러 코드 시리즈

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

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

댓글 남기기