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

22002
2026년 08월 15일 | DBMS Error 가이드

이 글에서 다루는 내용

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

22002 null value no indicator parameter 는?

PostgreSQL 에러 코드 22002는 null value no indicator parameter 라는 이름으로, 임베디드 SQL(Embedded SQL) 또는 ODBC/JDBC와 같은 인터페이스를 통해 데이터를 가져올 때 NULL 값을 수신할 변수에 인디케이터(indicator) 파라미터가 지정되지 않았을 때 발생합니다. 즉, 쿼리 결과에서 NULL이 반환되었지만, 호스트 변수(host variable)가 NULL을 처리할 수 있는 인디케이터 변수를 갖추지 않은 상황입니다. 이 에러는 특히 C 언어 기반의 ECPG(Embedded C for PostgreSQL) 환경이나, ODBC 드라이버를 통해 애플리케이션이 PostgreSQL과 통신할 때 자주 나타나며, NULL 처리 로직이 미흡한 레거시 코드에서도 빈번하게 발생합니다.


주요 발생 원인

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

ECPG 환경에서는 NULL 값을 받을 수 있는 컬럼을 SELECT할 때 반드시 인디케이터 변수를 함께 선언하고 사용해야 합니다. 인디케이터 변수 없이 NULL이 반환될 가능성이 있는 컬럼을 호스트 변수에 바인딩하면, PostgreSQL은 이 에러를 발생시켜 애플리케이션의 잘못된 NULL 처리로 인한 데이터 손상이나 오작동을 방지합니다. 예를 들어, nullable 컬럼을 단순 int 타입 호스트 변수에 연결하면 문제가 발생합니다.

2. ODBC/JDBC 드라이버에서의 NULL 처리 미흡

ODBC 드라이버를 사용하는 애플리케이션에서 SQLBindCol 또는 SQLGetData 함수를 호출할 때 NULL 인디케이터 버퍼(StrLen_or_IndPtr)를 NULL 포인터로 지정하면 동일한 에러가 발생할 수 있습니다. 드라이버가 결과 컬럼에서 NULL을 감지했을 때 이를 저장할 공간이 없으면 에러를 반환하게 됩니다. 이 경우는 특히 레거시 C/C++ 애플리케이션에서 오래된 ODBC 코드를 재사용할 때 자주 관찰됩니다.

3. NOT NULL 제약이 없는 컬럼에 대한 무방비 SELECT

테이블 설계 단계에서 NOT NULL 제약 조건을 설정하지 않은 컬럼은 언제든지 NULL 값을 가질 수 있습니다. 개발 초기에는 데이터가 항상 존재한다고 가정하고 인디케이터 없이 코드를 작성했지만, 운영 환경에서 실제 NULL 데이터가 입력되면서 에러가 터지는 패턴이 매우 흔합니다. 이처럼 테이블 스키마에 대한 이해 부족과 방어적 코딩 미흡이 결합되면 예기치 않은 장애로 이어집니다.


해결 방법

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

ECPG 코드에서 NULL이 반환될 수 있는 모든 호스트 변수에 반드시 인디케이터 변수를 선언하고 바인딩해야 합니다.

-- 문제가 되는 ECPG 코드 예시 (인디케이터 없음)
EXEC SQL SELECT salary INTO :emp_salary FROM employees WHERE emp_id = :id;

-- 올바른 ECPG 코드 예시 (인디케이터 변수 추가)
EXEC SQL BEGIN DECLARE SECTION;
    int emp_salary;
    short emp_salary_ind;  /* 인디케이터 변수: 0이면 정상, -1이면 NULL */
EXEC SQL END DECLARE SECTION;

EXEC SQL SELECT salary INTO :emp_salary INDICATOR :emp_salary_ind
         FROM employees WHERE emp_id = :id;

/* 애플리케이션 코드에서 인디케이터 확인 */
if (emp_salary_ind == -1) {
    printf("salary is NULL\n");
} else {
    printf("salary = %d\n", emp_salary);
}

원인 2 해결: NULL 반환을 피하기 위한 COALESCE 사용

쿼리 자체에서 NULL 반환을 방지하려면 COALESCE 또는 NULLIF 함수를 사용하여 NULL 대신 기본값을 반환하도록 합니다. 이 방법은 인디케이터 변수를 수정하기 어려운 레거시 코드 환경에서 가장 빠른 임시 해결책입니다.

-- NULL이 반환될 수 있는 위험한 쿼리
SELECT salary FROM employees WHERE emp_id = 1001;

-- COALESCE로 NULL을 기본값으로 치환하여 22002 에러 방지
SELECT COALESCE(salary, 0) AS salary FROM employees WHERE emp_id = 1001;

-- 문자열 컬럼의 경우
SELECT COALESCE(department_name, 'N/A') AS department_name
FROM departments WHERE dept_id = 50;

-- 복합 예시: 여러 컬럼의 NULL 처리
SELECT
    emp_id,
    COALESCE(first_name, '') AS first_name,
    COALESCE(last_name, 'Unknown') AS last_name,
    COALESCE(salary, 0) AS salary,
    COALESCE(bonus, 0) AS bonus
FROM employees
WHERE hire_date >= '2020-01-01';

원인 3 해결: NOT NULL 제약 조건 및 DEFAULT 값 설정

테이블 설계 단계에서 NULL이 허용되어서는 안 되는 컬럼에 NOT NULL 제약과 DEFAULT 값을 명시합니다.

-- 기존 테이블에 NOT NULL 제약 및 DEFAULT 추가
ALTER TABLE employees
    ALTER COLUMN salary SET NOT NULL,
    ALTER COLUMN salary SET DEFAULT 0;

ALTER TABLE employees
    ALTER COLUMN department_name SET DEFAULT 'Unassigned';

-- 새 테이블 생성 시 처음부터 NULL 방지 설계
CREATE TABLE employees (
    emp_id      SERIAL PRIMARY KEY,
    first_name  VARCHAR(100) NOT NULL DEFAULT '',
    last_name   VARCHAR(100) NOT NULL DEFAULT 'Unknown',
    salary      NUMERIC(12, 2) NOT NULL DEFAULT 0.00,
    hire_date   DATE NOT NULL DEFAULT CURRENT_DATE,
    department  VARCHAR(100) NOT NULL DEFAULT 'General'
);

-- NULL 가능성이 있는 데이터를 미리 확인하는 쿼리
SELECT column_name, is_nullable, column_default
FROM information_schema.columns
WHERE table_name = 'employees'
  AND table_schema = 'public'
ORDER BY ordinal_position;

추가 해결: psql에서 NULL 값 현황 파악

-- 특정 테이블에서 NULL 값이 존재하는 컬럼과 건수 확인
SELECT
    'salary' AS column_name,
    COUNT(*) FILTER (WHERE salary IS NULL) AS null_count,
    COUNT(*) AS total_count
FROM employees
UNION ALL
SELECT
    'department',
    COUNT(*) FILTER (WHERE department IS NULL),
    COUNT(*)
FROM employees;

예방 방법

1. 방어적 쿼리 작성 습관화 (COALESCE + IS NOT NULL 검사 병행)

모든 SELECT 쿼리에서 NULL이 반환될 가능성이 있는 컬럼은 COALESCE를 기본적으로 적용하고, 애플리케이션 코드에서도 반환값의 NULL 여부를 항상 확인하는 습관을 들여야 합니다. 특히 임베디드 SQL이나 ODBC를 사용하는 환경에서는 팀 내 코딩 표준에 “인디케이터 변수 필수 사용” 규칙을 명문화하고, 코드 리뷰 체크리스트에 포함시키는 것이 중요합니다.

2. 테이블 설계 시 NULL 허용 정책 명확화

신규 테이블 또는 컬럼 추가 시 해당 컬럼이 반드시 NULL을 허용해야 하는지 설계 문서에 명시합니다. NULL이 불필요한 컬럼은 항상 NOT NULL DEFAULT 조합으로 생성하고, 주기적으로 information_schema.columns를 조회하여 의도치 않게 NULL을 허용하는 컬럼이 없는지 감사(audit)하는 프로세스를 도입해야 합니다.


관련 에러

  • 22001 (string_data_right_truncation): 문자열 데이터가 대상 컬럼의 길이를 초과할 때 발생하며, 22002와 마찬가지로 데이터 타입 및 NULL 처리 미흡과 관련이 깊습니다.
  • 22003 (numeric_value_out_of_range): 숫자 값이 대상 데이터 타입의 범위를 벗어날 때 발생하며, 호스트 변수의 타입 불일치 문제와 함께 나타나는 경우가 많습니다.
  • 22004 (null_value_not_allowed): 특정 컨텍스트에서 NULL 값이 허용되지 않을 때 발생하며, 22002와 함께 NULL 관련 에러 코드 군을 형성합니다.
  • 42804 (datatype_mismatch): 호스트 변수의 데이터 타입이 컬럼 타입과 맞지 않을 때 발생하며, 임베디드 SQL 환경에서 22002와 함께 자주 등장합니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기