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

22002
2026년 06월 11일 | DBMS Error 가이드

이 글에서 다루는 내용

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

22002 null value no indicator parameter 는?

PostgreSQL 에러 코드 22002는 null value no indicator parameter로, 호스트 변수(host variable)에 NULL 값이 전달되었으나 해당 변수에 NULL 값을 수신할 수 있는 인디케이터 변수(indicator variable) 가 정의되어 있지 않을 때 발생합니다. 주로 C 언어 기반의 Embedded SQL(ECPG) 프로그램에서 데이터베이스 컬럼의 NULL 값을 호스트 변수로 가져오려 할 때 트리거됩니다. 인디케이터 변수는 NULL 여부를 추적하는 별도의 변수로, 이를 생략하면 런타임 에러가 발생합니다.


주요 발생 원인

1. ECPG(Embedded SQL in C)에서 인디케이터 변수 누락

가장 흔한 원인으로, C 프로그램에서 Embedded SQL을 사용할 때 NULL이 될 수 있는 컬럼 값을 인디케이터 변수 없이 호스트 변수에 직접 바인딩하는 경우입니다. PostgreSQL ECPG는 NULL 값을 일반 데이터 타입에 직접 매핑할 수 없으므로, 반드시 short 타입의 인디케이터 변수를 함께 선언하고 사용해야 합니다. 인디케이터 변수가 음수(-1)이면 NULL, 0이면 정상 값을 의미합니다.

2. FETCH 또는 SELECT INTO 시 NULL 컬럼 처리 미흡

커서(Cursor)를 사용하여 결과를 FETCH하거나 SELECT INTO로 변수에 직접 할당할 때, 해당 컬럼이 NULL 값을 포함하는 경우에도 발생합니다. 특히 OUTER JOIN 결과나 집계 함수의 결과, 혹은 부분적으로만 데이터가 입력된 테이블에서 NULL 컬럼을 읽어올 때 인디케이터 변수 없이 호스트 변수만 선언해 두면 이 에러가 발생합니다. 이는 런타임에만 감지되기 때문에 테스트 단계에서 NULL 데이터를 포함한 충분한 테스트가 필요합니다.

3. ODBC/JDBC 드라이버 설정 또는 바인딩 오류

ODBC나 일부 저수준 드라이버를 통해 PostgreSQL에 연결할 때, NULL 처리를 위한 길이 인디케이터(length indicator) 또는 NULL 인디케이터 버퍼가 올바르게 설정되지 않은 경우에도 유사한 에러가 발생할 수 있습니다. 특히 SQLBindCol 또는 SQLBindParameter 호출 시 StrLen_or_IndPtr 파라미터를 NULL 포인터로 넘기거나 잘못된 값을 설정하면 드라이버 레벨에서 이 에러가 전파됩니다. 드라이버 버전 업그레이드나 연결 설정 점검이 필요합니다.


해결 방법

원인 1 해결: ECPG에서 인디케이터 변수 추가

인디케이터 변수를 반드시 선언하고 호스트 변수와 함께 사용해야 합니다.

-- ECPG C 코드 내 예시 (Embedded SQL)
EXEC SQL BEGIN DECLARE SECTION;
    int     emp_id;
    char    emp_name[100];
    short   emp_name_ind;   /* 인디케이터 변수 선언 */
    float   salary;
    short   salary_ind;     /* salary 컬럼이 NULL일 수 있으므로 인디케이터 필요 */
EXEC SQL END DECLARE SECTION;

-- SELECT INTO 시 인디케이터 변수 함께 사용
EXEC SQL SELECT emp_id, emp_name, salary
         INTO :emp_id, :emp_name :emp_name_ind, :salary :salary_ind
         FROM employees
         WHERE emp_id = 101;

-- 인디케이터 변수로 NULL 여부 확인
if (salary_ind < 0) {
    printf("Salary is NULL\n");
} else {
    printf("Salary: %.2f\n", salary);
}

원인 2 해결: FETCH 시 인디케이터 변수 적용

커서를 사용한 FETCH에서도 동일하게 인디케이터 변수를 적용합니다.

-- 커서 선언 및 FETCH 예시
EXEC SQL DECLARE emp_cursor CURSOR FOR
    SELECT e.emp_id, e.emp_name, d.dept_name
    FROM employees e
    LEFT JOIN departments d ON e.dept_id = d.dept_id;  -- NULL 발생 가능

EXEC SQL BEGIN DECLARE SECTION;
    int   emp_id;
    char  emp_name[100];
    short emp_name_ind;
    char  dept_name[100];
    short dept_name_ind;   /* LEFT JOIN으로 NULL 가능 */
EXEC SQL END DECLARE SECTION;

EXEC SQL OPEN emp_cursor;

EXEC SQL FETCH emp_cursor
    INTO :emp_id, :emp_name :emp_name_ind, :dept_name :dept_name_ind;

if (dept_name_ind < 0) {
    printf("부서 미배정 직원입니다.\n");
}

EXEC SQL CLOSE emp_cursor;

원인 3 해결: 애플리케이션 레벨에서 NULL 방어 처리

데이터베이스 레벨에서 NULL이 전달되는 것을 원천 차단하거나, COALESCE로 기본값을 제공합니다.

-- COALESCE를 사용하여 NULL을 기본값으로 치환
SELECT
    emp_id,
    COALESCE(emp_name, 'Unknown')       AS emp_name,
    COALESCE(salary, 0.0)               AS salary,
    COALESCE(dept_name, 'Unassigned')   AS dept_name
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.dept_id;

-- 테이블 정의 시 NOT NULL 제약 조건 추가로 사전 예방
ALTER TABLE employees
    ALTER COLUMN emp_name SET NOT NULL,
    ALTER COLUMN emp_name SET DEFAULT 'Unknown';

-- NULL 데이터 사전 정리
UPDATE employees
SET salary = 0.0
WHERE salary IS NULL;

-- NULL 여부 확인 쿼리
SELECT column_name, is_nullable
FROM information_schema.columns
WHERE table_name = 'employees'
ORDER BY ordinal_position;

예방 방법

1. 모든 NULL 가능 컬럼에 인디케이터 변수 표준화

ECPG 개발 표준으로 NULL이 절대 발생하지 않는다고 확신하는 컬럼을 제외한 모든 호스트 변수에 인디케이터 변수를 짝으로 선언하는 규칙을 팀 내에서 강제화하는 것이 좋습니다. 특히 외래 키 컬럼, OUTER JOIN 결과, 집계 함수 결과는 반드시 인디케이터 변수와 함께 바인딩해야 합니다. 코드 리뷰 체크리스트에 “NULL 인디케이터 변수 존재 여부” 항목을 추가하여 자동화된 검수 프로세스를 도입하는 것을 권장합니다.

2. 테스트 데이터에 반드시 NULL 케이스 포함

단위 테스트 및 통합 테스트 시나리오에 NULL 값이 포함된 데이터셋을 반드시 포함시켜 NULL 처리 누락을 런타임 이전에 조기 발견해야 합니다. PostgreSQL의 information_schema.columns 뷰를 활용해 is_nullable = 'YES'인 컬럼 목록을 추출하고, 해당 컬럼들에 대한 NULL 테스트 케이스를 자동으로 생성하는 테스트 프레임워크를 구축하면 효과적입니다.


관련 에러

  • 22001 (string_data_right_truncation): 문자열 데이터가 호스트 변수의 크기를 초과할 때 발생하며, ECPG 환경에서 22002와 함께 자주 마주치는 에러입니다.
  • 22003 (numeric_value_out_of_range): 숫자형 호스트 변수의 범위를 초과한 값을 바인딩할 때 발생합니다.
  • 22000 (data_exception): 위 에러들의 상위 카테고리로, 데이터 변환 및 바인딩 관련 에러 전반을 포괄합니다.
  • 42804 (datatype_mismatch): 호스트 변수의 데이터 타입이 컬럼 타입과 일치하지 않을 때 발생하며, NULL 처리 오류와 복합적으로 나타나기도 합니다.
DBMS 에러 코드 시리즈

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

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

댓글 남기기