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

22022
2026년 06월 05일 | DBMS Error 가이드

이 글에서 다루는 내용

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

22022 indicator overflow 는?

PostgreSQL 에러 코드 22022는 indicator overflow 에러로, 주로 ECPG(Embedded C for PostgreSQL) 또는 외부 클라이언트 라이브러리에서 데이터베이스의 값을 호스트 변수(host variable)로 가져올 때 인디케이터 변수(indicator variable)가 표현할 수 있는 범위를 초과할 경우 발생합니다. 인디케이터 변수는 NULL 여부나 데이터 잘림(truncation) 여부를 전달하는 역할을 하는데, 이 변수가 처리하려는 값의 크기를 감당하지 못할 때 이 에러가 나타납니다. 실무에서는 대용량 문자열, NUMERIC 타입의 정밀도 초과, 또는 잘못 선언된 바인드 변수와 함께 나타나는 경우가 많습니다.


주요 발생 원인

  • 인디케이터 변수의 데이터 타입 불일치 또는 크기 부족

ECPG 또는 ODBC/JDBC 드라이버를 통해 데이터를 가져올 때, 인디케이터 변수는 반환되는 값의 길이나 NULL 상태를 저장하는 역할을 합니다. 만약 인디케이터 변수가 short 타입으로 선언되어 있는데 실제 반환되는 데이터의 길이가 short의 최대값(32767)을 초과하면 오버플로우가 발생합니다. 예를 들어, 수십만 바이트의 TEXT 컬럼 값을 short 인디케이터로 처리하려는 경우가 대표적입니다.

  • NUMERIC / DECIMAL 타입의 정밀도 또는 스케일 초과

데이터베이스에 저장된 NUMERIC 또는 DECIMAL 값의 자릿수(precision)나 소수점 이하 자릿수(scale)가 클라이언트 측 호스트 변수에 선언된 범위를 넘어설 때 이 에러가 발생할 수 있습니다. 예컨대 DB에는 NUMERIC(30, 10) 타입으로 값이 저장되어 있는데, 클라이언트 변수는 더 작은 정밀도로 선언된 경우 오버플로우가 생깁니다. 이 문제는 금융, 회계 시스템에서 큰 숫자를 다룰 때 특히 자주 등장합니다.

  • ECPG 호스트 변수 배열 또는 구조체 선언 오류

Embedded SQL(ECPG) 코드에서 배열이나 구조체 형태의 호스트 변수를 선언할 때 크기를 잘못 지정하거나 인디케이터 배열의 크기가 실제 반환 로우 수보다 작을 경우에도 이 에러가 발생합니다. 배열 페치(array fetch) 시나리오에서 인디케이터 배열의 원소 수가 부족하면 내부적으로 오버플로우 조건이 충족되어 에러가 트리거됩니다. 이런 문제는 컴파일 타임에 잡히지 않고 런타임에만 나타나기 때문에 디버깅이 어렵습니다.


해결 방법

원인 1 해결: 인디케이터 변수 타입을 충분히 크게 선언

ECPG 코드에서 인디케이터 변수를 short 대신 int 또는 long 타입으로 변경합니다.

-- ECPG 예제: 잘못된 선언
EXEC SQL BEGIN DECLARE SECTION;
    char large_text[100000];
    short ind;  /* 문제: short 타입은 32767까지만 표현 가능 */
EXEC SQL END DECLARE SECTION;

EXEC SQL SELECT content INTO :large_text :ind
FROM documents WHERE id = 1;
-- ECPG 예제: 올바른 선언 (int 또는 long 사용)
EXEC SQL BEGIN DECLARE SECTION;
    char large_text[100000];
    int ind;  /* 수정: int 타입으로 변경하여 오버플로우 방지 */
EXEC SQL END DECLARE SECTION;

EXEC SQL SELECT content INTO :large_text :ind
FROM documents WHERE id = 1;

순수 SQL 레벨에서 데이터를 미리 잘라서 가져오는 방법도 유효합니다:

-- 데이터를 미리 일정 길이로 잘라서 반환
SELECT LEFT(content, 32000) AS content_trimmed
FROM documents
WHERE id = 1;

원인 2 해결: NUMERIC 타입 캐스팅 및 정밀도 조정

DB에서 값을 가져올 때 명시적으로 캐스팅하여 클라이언트 변수 범위에 맞게 조정합니다.

-- 문제 상황: NUMERIC(30, 10) 값이 클라이언트 변수 범위를 초과
SELECT amount FROM financial_transactions WHERE id = 1;

-- 해결책 1: 명시적 캐스팅으로 정밀도 제한
SELECT amount::NUMERIC(15, 4) AS amount
FROM financial_transactions
WHERE id = 1;

-- 해결책 2: 문자열로 변환하여 클라이언트에서 처리
SELECT amount::TEXT AS amount_text
FROM financial_transactions
WHERE id = 1;

-- 해결책 3: 정밀도 초과 여부를 사전 확인
SELECT
    id,
    amount,
    length(amount::TEXT) AS digit_count,
    CASE
        WHEN length(amount::TEXT) > 15 THEN 'OVERFLOW_RISK'
        ELSE 'SAFE'
    END AS status
FROM financial_transactions;

원인 3 해결: ECPG 배열 페치 시 인디케이터 배열 크기 일치

-- ECPG 배열 페치 예제: 인디케이터 배열 크기 불일치 (잘못된 예)
EXEC SQL BEGIN DECLARE SECTION;
    int ids[100];
    char names[100][50];
    short ind[10];  /* 문제: 배열 크기 불일치 */
EXEC SQL END DECLARE SECTION;

-- 올바른 예: 인디케이터 배열 크기를 호스트 변수 배열과 동일하게 맞춤
EXEC SQL BEGIN DECLARE SECTION;
    int ids[100];
    char names[100][50];
    int ind[100];  /* 수정: 동일한 크기로 선언 */
EXEC SQL END DECLARE SECTION;

EXEC SQL DECLARE cur CURSOR FOR
    SELECT id, name FROM employees ORDER BY id;

EXEC SQL OPEN cur;
EXEC SQL FETCH 100 FROM cur INTO :ids, :names :ind;
EXEC SQL CLOSE cur;

실제 반환 행 수를 미리 확인하는 것도 좋은 습관입니다:

-- 반환될 행 수 사전 확인
SELECT COUNT(*) FROM employees;

-- 또는 LIMIT을 사용하여 배열 크기 내로 제한
SELECT id, name
FROM employees
ORDER BY id
LIMIT 100;

예방 방법

  • 인디케이터 변수와 호스트 변수는 항상 int 또는 long 타입으로 표준화

실무에서는 short 타입의 인디케이터 변수 사용을 코딩 표준으로 금지하고, 모든 인디케이터 변수를 int 이상의 타입으로 통일하는 것이 좋습니다. 특히 TEXT, VARCHAR, NUMERIC 등 가변 길이 또는 큰 정밀도를 가질 수 있는 컬럼을 다룰 때는 반드시 이 규칙을 따르십시오. CI/CD 파이프라인에 정적 분석 도구를 통합하여 short 인디케이터 선언을 자동으로 감지하고 경고를 발생시키는 체계를 구축하면 더욱 효과적입니다.

  • 스키마 변경 시 클라이언트 코드의 인디케이터 변수 크기를 동기화하는 프로세스 수립

DB 스키마의 컬럼 타입이나 정밀도가 변경될 때, 이를 사용하는 ECPG 또는 기타 임베디드 SQL 코드의 호스트 변수와 인디케이터 변수도 함께 검토하는 변경 관리 프로세스를 반드시 마련해야 합니다. 아래와 같이 information_schema를 활용하여 정밀도가 큰 컬럼을 주기적으로 모니터링하고, 클라이언트 코드 리뷰 체크리스트에 인디케이터 크기 검토 항목을 포함시키는 것을 권장합니다.

“`sql

— 정밀도가 높은 NUMERIC 컬럼 목록 조회 (모니터링 쿼리)

SELECT

table_schema,

table_name,

column_name,

data_type,

numeric_precision,

numeric_scale,

character_maximum_length

FROM information_schema.columns

WHERE

table_schema NOT IN (‘pg_catalog’, ‘information_schema’)

AND (

(data_type IN (‘numeric’, ‘decimal’) AND numeric_precision > 15)

OR (data_type IN (‘text’, ‘character varying’) AND

(character_maximum_length IS NULL OR character_maximum_length > 32767))

)

ORDER BY table_schema, table_name, column_name;

“`


관련 에러

  • 22001 (string_data_right_truncation): 문자열 데이터가 대상 변수의 길이를 초과할 때 발생하며, indicator overflow와 함께 나타나는 경우가 많습니다.
  • 22003 (numeric_value_out_of_range): NUMERIC 값이 대상 타입의 범위를 벗어날 때 발생하며, 정밀도 초과 문제와 밀접하게 연관됩니다.
  • 22P02 (invalid_text_representation): 타입 변환 실패 시 발생하며, 잘못된 캐스팅 해결 과정에서 마주칠 수 있습니다.
  • 07002 (count_field_overflow): 결과 집합의 컬럼 수가 INTO 절의 변수 수보다 많을 때 발생하는 관련 에러입니다.
DBMS 에러 코드 시리즈

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

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

댓글 남기기