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

42804
2026년 07월 06일 | DBMS Error 가이드

이 글에서 다루는 내용

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

42804 datatype mismatch 는?

PostgreSQL 에러 코드 42804는 datatype mismatch 에러로, SQL 쿼리나 함수, 연산자 등에서 서로 호환되지 않는 데이터 타입을 사용하려고 할 때 발생합니다. 예를 들어, CASE 표현식의 각 분기가 서로 다른 타입을 반환하거나, UNION 쿼리에서 대응하는 컬럼의 타입이 일치하지 않을 때 이 에러가 트리거됩니다. PostgreSQL은 엄격한 타입 시스템을 채택하고 있기 때문에, 암묵적으로 변환이 불가능한 타입 간의 조합을 발견하면 즉시 이 에러를 발생시켜 데이터 무결성을 보호합니다.


주요 발생 원인

  • CASE 표현식 또는 UNION에서의 타입 불일치

CASE WHEN ... THEN ... ELSE ... 구문에서 각 THEN 절과 ELSE 절이 서로 다른 데이터 타입 값을 반환할 때 가장 흔하게 이 에러가 발생합니다. 마찬가지로 UNION, UNION ALL, INTERSECT, EXCEPT 등의 집합 연산에서 대응하는 컬럼의 타입이 일치하지 않으면 PostgreSQL은 42804 에러를 반환합니다. 실무에서는 레거시 코드나 여러 개발자가 함께 작업하는 환경에서 특히 자주 목격되는 패턴입니다.

  • 함수 또는 저장 프로시저의 반환 타입 불일치

CREATE FUNCTION 또는 CREATE PROCEDURE로 함수를 정의할 때, 선언된 반환 타입(RETURNS 절)과 실제 함수 본문이 반환하는 값의 타입이 다를 경우 이 에러가 발생합니다. 특히 PL/pgSQL 함수에서 RETURN 문이 반환하는 값의 타입과 함수 시그니처가 다를 때, 또는 OUT 파라미터의 타입이 맞지 않을 때 자주 발생합니다. 함수를 수정하거나 마이그레이션 후 타입이 바뀐 테이블을 참조할 때 특히 주의가 필요합니다.

  • 배열 타입 또는 복합 타입(Composite Type)에서의 불일치

배열 리터럴을 잘못된 타입으로 캐스팅하거나, ARRAY[...] 생성자 내부에 서로 다른 타입의 요소를 넣을 때 42804 에러가 발생할 수 있습니다. 또한 복합 타입(Row Type)을 함수에 전달하거나 테이블에 삽입할 때 내부 필드의 타입이 선언된 것과 다르면 동일한 에러가 발생합니다. 최근 JSON/JSONB 컬럼과 일반 컬럼 간의 비교 또는 대입 연산에서도 빈번히 목격됩니다.


해결 방법

1. CASE / UNION 타입 불일치 해결

문제가 되는 쿼리 예시:

-- 에러 발생: CASE의 THEN은 integer, ELSE는 text를 반환
SELECT
    CASE
        WHEN score >= 90 THEN 1
        ELSE 'Pass'
    END AS result
FROM students;
-- ERROR:  42804: CASE types integer and text cannot be matched

해결 방법 — 명시적 타입 캐스팅(CAST) 또는 :: 연산자 사용:

-- 해결책 1: 모든 분기를 TEXT로 통일
SELECT
    CASE
        WHEN score >= 90 THEN '1'
        ELSE 'Pass'
    END AS result
FROM students;

-- 해결책 2: CAST를 사용하여 명시적으로 변환
SELECT
    CASE
        WHEN score >= 90 THEN CAST(1 AS TEXT)
        ELSE 'Pass'
    END AS result
FROM students;

-- UNION 타입 불일치 해결
-- 에러 발생 예시
SELECT id, name FROM employees
UNION
SELECT id, salary FROM employees;  -- name(text) vs salary(numeric) 불일치

-- 해결: salary를 text로 캐스팅
SELECT id, name FROM employees
UNION
SELECT id, salary::TEXT FROM employees;

2. 함수 반환 타입 불일치 해결

문제가 되는 함수 예시:

-- 에러 발생: 반환 타입은 INTEGER인데 TEXT를 반환
CREATE OR REPLACE FUNCTION get_employee_code(emp_id INT)
RETURNS INTEGER AS $$
BEGIN
    RETURN 'EMP-' || emp_id::TEXT;  -- TEXT를 반환하려 함
END;
$$ LANGUAGE plpgsql;
-- ERROR: 42804: return type mismatch in function declared to return integer

해결 방법:

-- 해결책 1: 반환 타입을 TEXT로 변경
CREATE OR REPLACE FUNCTION get_employee_code(emp_id INT)
RETURNS TEXT AS $$
BEGIN
    RETURN 'EMP-' || emp_id::TEXT;
END;
$$ LANGUAGE plpgsql;

-- 해결책 2: 반환값을 선언된 타입에 맞게 수정
CREATE OR REPLACE FUNCTION get_employee_id(emp_code TEXT)
RETURNS INTEGER AS $$
DECLARE
    result INTEGER;
BEGIN
    -- TEXT를 INTEGER로 변환하여 반환
    SELECT id INTO result
    FROM employees
    WHERE code = emp_code;
    RETURN result;  -- INTEGER 반환
END;
$$ LANGUAGE plpgsql;

3. 배열 및 복합 타입 불일치 해결

-- 에러 발생: 배열 내 혼합 타입
SELECT ARRAY[1, 2, 'three'];
-- ERROR: 42804: array cannot be created from components of different types

-- 해결책: 모든 요소를 동일한 타입으로 캐스팅
SELECT ARRAY[1::TEXT, 2::TEXT, 'three'];
-- 또는
SELECT ARRAY['1', '2', 'three'];

-- 복합 타입 불일치 해결
-- 테이블 정의
CREATE TABLE product (
    id SERIAL PRIMARY KEY,
    price NUMERIC(10,2),
    quantity INTEGER
);

-- 에러 발생: price 컬럼에 TEXT 삽입 시도
INSERT INTO product (price, quantity) VALUES ('열다섯', 100);
-- ERROR: 42804: invalid input syntax / column "price" is of type numeric

-- 해결책: 올바른 타입으로 삽입
INSERT INTO product (price, quantity) VALUES (15.00, 100);

-- 또는 명시적 캐스팅
INSERT INTO product (price, quantity) VALUES ('15.00'::NUMERIC, 100);

-- JSONB와 일반 컬럼 비교 시 타입 캐스팅
SELECT *
FROM orders
WHERE metadata->>'amount' = total_amount::TEXT;
-- metadata->>'amount'는 TEXT를 반환하므로 total_amount를 TEXT로 변환

예방 방법

  • 명시적 타입 캐스팅 습관화 및 코드 리뷰 강화

SQL 코드 작성 시 암묵적 타입 변환에 의존하지 않고, 항상 CAST() 함수나 :: 캐스팅 연산자를 사용하여 타입을 명시적으로 변환하는 습관을 들이세요. CI/CD 파이프라인에 pg_dump --schema-only 또는 psql을 활용한 SQL 문법 검증 단계를 추가하고, PR(Pull Request) 코드 리뷰 시 타입 관련 변경 사항을 반드시 확인하는 프로세스를 정착시키는 것이 중요합니다. 특히 마이그레이션 스크립트에서 컬럼 타입을 변경할 때는 해당 컬럼을 참조하는 모든 뷰, 함수, 트리거를 함께 검토해야 합니다.

  • 도메인 타입과 강한 타입 검사 도구 활용

PostgreSQL의 DOMAIN 타입을 적극 활용하여 비즈니스 로직에 맞는 커스텀 타입을 정의하고, 잘못된 타입의 데이터가 처음부터 저장되지 않도록 방어하세요. 또한 pgTAP과 같은 데이터베이스 단위 테스트 프레임워크를 도입하여 함수와 쿼리의 반환 타입을 자동으로 검증하는 테스트를 작성하면, 타입 불일치 에러를 프로덕션 배포 전에 조기에 발견할 수 있습니다. ORM(Object-Relational Mapping) 도구를 사용하는 경우에도 스키마 동기화 상태를 주기적으로 확인하는 것이 좋습니다.


관련 에러

  • 42883 (undefined_function): 특정 타입 조합에 맞는 함수나 연산자 오버로드가 존재하지 않을 때 발생하며, 42804와 함께 타입 관련 에러의 대표적인 쌍입니다.
  • 22P02 (invalid_text_representation): TEXT 타입의 값을 다른 타입으로 변환할 때 형식이 맞지 않으면 발생하며, 42804의 해결 과정 중 캐스팅 시 만날 수 있습니다.
  • 42P18 (indeterminate_datatype): 파라미터 또는 리터럴의 타입을 결정할 수 없을 때 발생하며, 동적 쿼리 작성 시 42804와 함께 자주 등장합니다.
  • 42601 (syntax_error): 타입 캐스팅 문법 오류 시 발생하며, 42804를 수정하는 과정에서 캐스팅 코드를 잘못 작성했을 때 마주칠 수 있습니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기