2026년 10월 13일 | DBMS Error 가이드
이 글에서 다루는 내용
22022 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
22022 indicator overflow 는?
PostgreSQL 에러 코드 22022는 indicator overflow 에러로, 주로 ECPG(Embedded C for PostgreSQL) 또는 ODBC/JDBC 드라이버를 통해 데이터베이스와 통신할 때 호스트 변수의 인디케이터(indicator) 변수가 표현할 수 있는 범위를 초과하는 경우 발생합니다. 인디케이터 변수는 NULL 값이나 데이터 잘림(truncation) 여부를 클라이언트 애플리케이션에 전달하는 역할을 하는데, 이 변수가 담을 수 없을 만큼 큰 값이 반환되거나, 잘린 데이터의 크기가 인디케이터의 최대 표현 범위를 넘어설 때 이 에러가 발생합니다. 실무에서는 대용량 문자열이나 바이너리 데이터를 소형 버퍼 변수에 매핑하려 할 때 자주 마주치게 됩니다.
주요 발생 원인
1. 인디케이터 변수의 데이터 타입 범위 초과
ECPG 또는 Pro*C 스타일의 임베디드 SQL에서 인디케이터 변수는 보통 short (2바이트 정수) 타입으로 선언됩니다. short 타입의 최대값은 32,767인데, 반환되는 데이터의 실제 길이가 이 값을 초과하면 인디케이터 변수가 해당 값을 저장하지 못하고 overflow가 발생합니다. 예를 들어 수만 자의 텍스트 데이터를 short 인디케이터로 처리하려 할 때 이 문제가 발생합니다.
2. 버퍼 크기보다 큰 데이터 수신 시 잘림(Truncation) 정보 전달 실패
PostgreSQL이 클라이언트 버퍼보다 더 큰 데이터를 반환할 때, 드라이버는 인디케이터 변수에 원래 데이터 크기를 기록하여 애플리케이션이 데이터가 잘렸음을 인지하도록 합니다. 그런데 원래 데이터의 크기가 인디케이터 변수의 최대 범위(예: short의 경우 32,767)보다 크면, 이 크기 정보 자체를 저장할 수 없어 overflow 에러가 발생하게 됩니다. 특히 TEXT, VARCHAR, BYTEA 컬럼에 매우 큰 값이 저장되어 있을 때 빈번하게 나타납니다.
3. ODBC/JDBC 드라이버 설정 또는 버전 불일치
오래된 버전의 ODBC 드라이버나 잘못 설정된 JDBC 드라이버를 사용하면 인디케이터 처리 로직에 버그가 존재할 수 있습니다. 드라이버가 PostgreSQL 서버로부터 받은 데이터 크기를 올바르게 변환하지 못하거나, 내부 버퍼 관리가 비효율적으로 구현된 경우에도 이 에러가 발생할 수 있습니다. 드라이버 버전과 PostgreSQL 서버 버전 간의 호환성 문제도 중요한 원인 중 하나입니다.
해결 방법
원인 1 해결: 인디케이터 변수 타입을 더 큰 정수형으로 변경
ECPG 코드에서 인디케이터 변수를 short 대신 int 또는 long으로 선언하여 더 넓은 범위의 값을 수용하도록 변경합니다.
-- ECPG 예제: 인디케이터 변수 타입 변경
-- 변경 전 (문제 발생 가능)
EXEC SQL BEGIN DECLARE SECTION;
char description[100];
short description_ind; -- 최대 32,767까지만 표현 가능
EXEC SQL END DECLARE SECTION;
-- 변경 후 (권장)
EXEC SQL BEGIN DECLARE SECTION;
char description[65536];
int description_ind; -- int로 변경하여 더 큰 범위 수용
EXEC SQL END DECLARE SECTION;
-- 데이터 조회 시 인디케이터 변수와 함께 사용
EXEC SQL SELECT description INTO :description :description_ind
FROM products
WHERE product_id = 1001;
원인 2 해결: 데이터 크기를 미리 제한하거나 서버 사이드에서 트리밍
쿼리 레벨에서 반환 데이터의 크기를 미리 제한하면 인디케이터 overflow를 원천 차단할 수 있습니다.
-- 방법 1: LEFT() 함수로 반환 길이 제한
SELECT
product_id,
LEFT(description, 32000) AS description, -- 32,767 미만으로 제한
LENGTH(description) AS original_length -- 원본 길이는 별도 컬럼으로 확인
FROM products
WHERE product_id = 1001;
-- 방법 2: SUBSTRING() 으로 필요한 부분만 추출
SELECT
product_id,
SUBSTRING(large_text_column FROM 1 FOR 10000) AS partial_text
FROM large_data_table
WHERE id = 42;
-- 방법 3: 데이터 길이 검사 후 처리 분기
SELECT
product_id,
CASE
WHEN LENGTH(description) > 32000
THEN LEFT(description, 32000) || '...[truncated]'
ELSE description
END AS safe_description
FROM products;
원인 3 해결: 드라이버 업그레이드 및 연결 파라미터 조정
ODBC나 JDBC 드라이버를 최신 버전으로 업그레이드하고, 드라이버의 버퍼 설정을 검토합니다.
-- PostgreSQL 서버에서 현재 연결 드라이버 정보 확인
SELECT
application_name,
client_addr,
state,
query
FROM pg_stat_activity
WHERE datname = current_database();
-- 드라이버 버전 확인을 위한 연결 정보 조회
SELECT version(); -- PostgreSQL 서버 버전 확인
-- JDBC 연결 시 defaultRowFetchSize 설정 확인 (Java 애플리케이션)
-- jdbc:postgresql://localhost:5432/mydb?defaultRowFetchSize=100&prepareThreshold=5
-- 큰 오브젝트 데이터 처리 시 스트리밍 방식 활용 (Large Object)
SELECT lo_get(large_object_oid) FROM my_large_object_table WHERE id = 1;
-- 또는 largeobject API를 통한 청크 단위 읽기
SELECT lo_get(large_object_oid, 0, 32000) AS chunk_1
FROM my_large_object_table WHERE id = 1;
예방 방법
1. 스키마 설계 단계에서 컬럼 길이 적절히 제한하기
대용량 텍스트가 반드시 필요하지 않은 컬럼에는 TEXT 대신 길이 제한이 있는 VARCHAR(n)을 사용하고, 제약 조건(CHECK CONSTRAINT)을 통해 데이터 길이를 데이터베이스 수준에서 관리합니다.
-- 권장: 컬럼 길이 제약 조건 명시
CREATE TABLE products (
product_id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description VARCHAR(10000), -- 명시적 길이 제한
summary VARCHAR(500),
CONSTRAINT chk_description_length CHECK (LENGTH(description) <= 10000)
);
-- 기존 테이블에 체크 제약 추가
ALTER TABLE products
ADD CONSTRAINT chk_summary_length
CHECK (LENGTH(summary) <= 500);
2. 애플리케이션 레이어에서 데이터 크기 검증 및 모니터링
애플리케이션 코드에서 데이터를 INSERT/UPDATE 하기 전에 길이 검증 로직을 추가하고, 운영 중에는 컬럼별 최대 데이터 크기를 주기적으로 모니터링하여 잠재적 overflow 위험을 사전에 탐지합니다.
-- 모니터링: 각 컬럼의 실제 최대 데이터 길이 주기적 점검
SELECT
'description' AS column_name,
MAX(LENGTH(description)) AS max_length,
AVG(LENGTH(description))::INT AS avg_length,
COUNT(*) FILTER (WHERE LENGTH(description) > 30000) AS risky_rows
FROM products
UNION ALL
SELECT
'summary',
MAX(LENGTH(summary)),
AVG(LENGTH(summary))::INT,
COUNT(*) FILTER (WHERE LENGTH(summary) > 30000)
FROM products;
관련 에러
- 22001 (string_data_right_truncation): 문자열 데이터가 대상 컬럼의 최대 길이를 초과하여 잘릴 때 발생하며,
22022와 함께 대용량 데이터 처리 시 자주 동반됩니다. - 22003 (numeric_value_out_of_range): 숫자 값이 대상 데이터 타입의 범위를 초과할 때 발생하며, 인디케이터 overflow와 유사한 범위 초과 문제입니다.
- 22007 (invalid_datetime_format): 날짜/시간 데이터 변환 오류로, 클라이언트-서버 간 데이터 타입 불일치 문제라는 점에서
22022와 원인 맥락이 유사합니다. - 22P02 (invalid_text_representation): 텍스트를 특정 데이터 타입으로 변환하는 데 실패할 때 발생하며, 드라이버 데이터 변환 문제와 연관될 수 있습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.