2026년 06월 09일 | DBMS Error 가이드
이 글에서 다루는 내용
22023 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
22023 invalid parameter value 는?
PostgreSQL 에러 코드 22023(invalid_parameter_value)은 함수나 명령어에 전달된 파라미터 값이 허용 범위를 벗어나거나 잘못된 형식일 때 발생하는 오류입니다. 주로 내장 함수, 타입 변환, 설정 명령어(SET), 또는 특정 연산자에 유효하지 않은 값을 넘겼을 때 트리거됩니다. SQL 표준 SQLSTATE 클래스 22(데이터 예외) 계열에 속하며, 데이터 처리 중 런타임 단계에서 발생하기 때문에 애플리케이션 레벨에서 반드시 적절한 예외 처리가 필요합니다.
주요 발생 원인
1. 날짜/시간 함수에 잘못된 형식 또는 범위의 값 전달
PostgreSQL의 날짜 및 시간 관련 함수(date_trunc, to_timestamp, interval 등)는 입력값의 형식과 범위에 매우 엄격합니다. 예를 들어 date_trunc에 유효하지 않은 단위 문자열(예: 'weekday')을 전달하거나, make_interval에 허용 범위를 초과하는 값을 넣으면 즉시 22023 에러가 발생합니다. 특히 외부 입력값을 검증 없이 함수에 직접 주입할 경우 운영 환경에서 빈번하게 발생하는 문제입니다.
2. SET 명령어 또는 pg_catalog 설정 함수에 잘못된 값 전달
SET work_mem = '-1kB'처럼 의미적으로 잘못된 값이나, set_config() 함수에 허용되지 않는 파라미터를 전달할 때 이 에러가 발생합니다. PostgreSQL 설정 파라미터는 각각 허용 가능한 값의 타입, 범위, 단위가 명확하게 정의되어 있으며 이를 벗어나면 예외를 일으킵니다. 동적으로 설정을 변경하는 코드에서 사용자 입력을 그대로 반영할 때 특히 위험합니다.
3. 정규식 또는 문자열 처리 함수에 잘못된 플래그/옵션 전달
regexp_match, regexp_replace, substring 등 정규식 기반 함수에 잘못된 플래그 문자를 전달하거나, encode/decode 함수에 지원하지 않는 인코딩 형식을 지정할 때 22023 에러가 발생합니다. 예를 들어 encode(data, 'utf8')처럼 지원하지 않는 인코딩 이름을 사용하면 런타임에 오류가 발생합니다. 문자열 처리 로직이 복잡한 애플리케이션에서 동적으로 함수 옵션을 구성할 때 주의가 필요합니다.
해결 방법
원인 1 해결: 날짜/시간 함수 파라미터 검증
date_trunc에 허용된 단위 값만 전달하도록 코드를 수정해야 합니다.
-- 에러 발생 예시
SELECT date_trunc('weekday', now());
-- ERROR: 22023: units "weekday" not recognized
-- 올바른 사용 예시 (허용된 단위: microseconds, milliseconds, second, minute,
-- hour, day, week, month, quarter, year, decade, century, millennium)
SELECT date_trunc('week', now());
SELECT date_trunc('month', now());
-- make_interval 에러 예시
SELECT make_interval(years => 999999999);
-- ERROR: 22023: interval out of range
-- 안전한 사용 예시
SELECT make_interval(years => 9999);
-- 동적 단위를 사용하는 경우, 화이트리스트 검증 함수 활용
CREATE OR REPLACE FUNCTION safe_date_trunc(unit TEXT, ts TIMESTAMPTZ)
RETURNS TIMESTAMPTZ AS $$
DECLARE
allowed_units TEXT[] := ARRAY['microseconds','milliseconds','second','minute',
'hour','day','week','month','quarter',
'year','decade','century','millennium'];
BEGIN
IF unit = ANY(allowed_units) THEN
RETURN date_trunc(unit, ts);
ELSE
RAISE EXCEPTION 'Invalid date_trunc unit: %', unit
USING ERRCODE = '22023';
END IF;
END;
$$ LANGUAGE plpgsql;
-- 사용 예시
SELECT safe_date_trunc('month', now());
SELECT safe_date_trunc('weekday', now()); -- 명확한 에러 메시지 반환
원인 2 해결: SET 명령어 및 설정 파라미터 검증
-- 에러 발생 예시
SET work_mem = '-1kB';
-- ERROR: 22023: invalid value for parameter "work_mem": "-1kB"
SET client_min_messages = 'verbose_extra';
-- ERROR: 22023: invalid value for parameter "client_min_messages": "verbose_extra"
-- 올바른 사용 예시
SET work_mem = '64MB';
SET client_min_messages = 'notice';
-- set_config를 사용하는 경우
SELECT set_config('work_mem', '128MB', false);
-- 현재 유효한 설정값 확인
SELECT name, setting, unit, min_val, max_val, enumvals
FROM pg_settings
WHERE name = 'work_mem';
-- 동적 설정 변경 전 유효성 검사 패턴
DO $$
DECLARE
param_name TEXT := 'work_mem';
param_value TEXT := '64MB';
v_min TEXT;
v_max TEXT;
BEGIN
-- 파라미터 존재 여부 사전 확인
IF NOT EXISTS (SELECT 1 FROM pg_settings WHERE name = param_name) THEN
RAISE EXCEPTION 'Unknown parameter: %', param_name;
END IF;
-- 실제 적용 (에러 발생 시 트랜잭션 롤백)
PERFORM set_config(param_name, param_value, false);
RAISE NOTICE 'Parameter % set to %', param_name, param_value;
EXCEPTION
WHEN invalid_parameter_value THEN
RAISE EXCEPTION 'Invalid value "%" for parameter "%"', param_value, param_name;
END;
$$;
원인 3 해결: 정규식 및 인코딩 함수 파라미터 수정
-- 에러 발생 예시: 잘못된 정규식 플래그
SELECT regexp_match('hello world', 'hello', 'z');
-- ERROR: 22023: invalid regular expression option: "z"
-- 올바른 플래그 사용 (g는 regexp_replace에서만 유효)
-- 유효한 플래그: i(대소문자 무시), g(전체 치환, regexp_replace 전용),
-- m(멀티라인), s(. 이 newline 포함), x(공백 무시)
SELECT regexp_match('Hello World', 'hello', 'i');
SELECT regexp_replace('hello world', 'o', '0', 'g');
-- encode/decode 에러 예시
SELECT encode('test'::bytea, 'utf8');
-- ERROR: 22023: invalid encoding name "utf8"
-- 올바른 인코딩 형식 (hex, base64, escape 만 지원)
SELECT encode('test'::bytea, 'base64');
SELECT encode('test'::bytea, 'hex');
SELECT decode('74657374', 'hex');
-- PL/pgSQL에서 안전한 예외 처리 패턴
CREATE OR REPLACE FUNCTION safe_encode(data BYTEA, fmt TEXT)
RETURNS TEXT AS $$
BEGIN
RETURN encode(data, fmt);
EXCEPTION
WHEN invalid_parameter_value THEN
RAISE WARNING 'Unsupported encoding format: %. Using base64.', fmt;
RETURN encode(data, 'base64');
END;
$$ LANGUAGE plpgsql;
예방 방법
1. 입력값 화이트리스트 검증 및 PL/pgSQL 예외 처리 표준화
외부로부터 입력받은 값을 PostgreSQL 내장 함수에 직접 전달하기 전에 반드시 허용된 값 목록(화이트리스트)과 대조하는 검증 레이어를 두어야 합니다. 또한 PL/pgSQL 함수 내에서는 EXCEPTION WHEN invalid_parameter_value THEN 블록을 표준 패턴으로 채택하여 런타임 오류를 애플리케이션 장애로 전파되지 않도록 방어적으로 처리해야 합니다. CI/CD 파이프라인에 SQL 단위 테스트(예: pgTAP)를 포함시켜 경계값 및 비정상 입력에 대한 테스트 커버리지를 확보하는 것도 효과적인 예방책입니다.
2. pg_settings 뷰와 문서 기반의 파라미터 범위 사전 확인
데이터베이스 설정을 동적으로 변경하는 코드를 작성할 때는 반드시 pg_settings 뷰의 min_val, max_val, enumvals 컬럼을 참조하여 허용 범위를 코드에 명시적으로 반영해야 합니다. 배포 전 스테이징 환경에서 SET 명령어와 함수 호출에 대한 통합 테스트를 수행하고, PostgreSQL 버전 업그레이드 시 파라미터 허용값이 변경될 수 있으므로 릴리즈 노트를 반드시 검토하는 습관을 가져야 합니다.
관련 에러
- 22000 (
data_exception): 22023의 상위 클래스로, 데이터 관련 모든 런타임 예외의 기본 에러입니다. - 22007 (
invalid_datetime_format): 날짜/시간 문자열 파싱 실패 시 발생하며 22023과 함께 날짜 처리 로직에서 자주 동반 발생합니다. - 22008 (
datetime_field_overflow): 날짜/시간 값이 허용 범위를 초과할 때 발생하며,make_interval관련 22023과 유사한 맥락에서 나타납니다. - 42704 (
undefined_object):SET명령어에 존재하지 않는 파라미터 이름을 사용할 때 발생하며, 22023과 혼동하기 쉬운 설정 관련 에러입니다. - 22P02 (
invalid_text_representation): 잘못된 텍스트 형식으로 타입 변환 실패 시 발생하며 22023과 함께 데이터 정제 파이프라인에서 빈번하게 등장합니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.