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

0100C
2026년 07월 31일 | DBMS Error 가이드

이 글에서 다루는 내용

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

0100C dynamic result sets returned 는?

PostgreSQL 에러 코드 0100Cdynamic_result_sets_returned 경고(Warning)로, SQL 저장 프로시저(Stored Procedure)가 호출자(caller)에게 반환할 것으로 선언된 것보다 더 많은 동적 결과 집합(dynamic result sets)을 반환할 때 발생합니다. 이 에러는 엄밀히 말하면 치명적인 오류(error)가 아닌 경고(warning) 수준의 메시지이며, SQL 표준과의 호환성을 위해 PostgreSQL이 발생시킵니다. 주로 PL/pgSQL 또는 PL/Python, PL/Perl 등의 언어로 작성된 프로시저에서 RESULT SETS 절을 잘못 선언하거나, 프로시저 내부 로직이 변경되어 실제 반환되는 결과 집합 수와 선언된 수가 일치하지 않을 때 나타납니다.


주요 발생 원인

1. RESULT SETS 선언 값과 실제 반환 결과 집합 수 불일치

가장 빈번하게 발생하는 원인으로, 프로시저를 처음 작성할 때 RESULT SETS N으로 선언해 두었지만, 이후 로직 변경으로 인해 실제로 반환되는 커서나 결과 집합이 늘어나는 경우입니다. PostgreSQL은 SQL/PSM(Persistent Stored Modules) 표준을 따르기 위해 프로시저 시그니처에 반환할 결과 집합 수를 명시할 수 있도록 지원하며, 이 값과 실제 실행 결과가 다르면 0100C 경고를 발생시킵니다. 특히 대규모 팀에서 코드 리뷰 없이 프로시저 본문만 수정하고 시그니처는 업데이트하지 않는 경우에 자주 나타납니다.

2. 조건 분기(IF/CASE)에 따른 가변적인 결과 집합 반환

프로시저 내부에서 IFCASE 조건에 따라 반환하는 결과 집합의 수가 달라지는 경우에도 이 경고가 발생할 수 있습니다. 예를 들어 특정 파라미터 값에 따라 하나의 결과 집합을 반환할 수도 있고, 두 개를 반환할 수도 있는 경우, 선언된 RESULT SETS 값이 어느 한쪽과만 일치하면 나머지 경우에서 경고가 발생합니다. 이런 패턴은 동적 쿼리(dynamic query)를 많이 활용하는 리포트 생성 프로시저에서 자주 볼 수 있습니다.

3. 마이그레이션 또는 외부 도구 자동 변환 시 선언 누락

Oracle, DB2, SQL Server 등 타 DBMS에서 PostgreSQL로 마이그레이션할 때, 자동 변환 도구가 RESULT SETS 절을 잘못 번역하거나 누락시키는 경우가 있습니다. 또한 ORM(Object Relational Mapper) 또는 자동 코드 생성 도구가 프로시저를 생성할 때 기본값으로 RESULT SETS 1을 넣어 두었는데, 실제 로직에서 여러 개의 커서를 열거나 여러 SELECT를 반환하는 경우도 해당됩니다. 이 경우 개별 프로시저를 하나씩 검토해야 하므로 운영 환경에서 발견 시 수정 비용이 큽니다.


해결 방법

원인 1 해결: RESULT SETS 선언 값 수정

프로시저 정의에서 RESULT SETS 값을 실제 반환되는 결과 집합 수에 맞게 수정합니다.

-- 기존 잘못된 프로시저 (RESULT SETS 1로 선언되어 있으나 실제로는 2개 반환)
CREATE OR REPLACE PROCEDURE get_employee_data(dept_id INT)
LANGUAGE SQL
RESULT SETS 1  -- 잘못된 선언
AS $$
  -- 첫 번째 결과 집합
  SELECT employee_id, employee_name, salary
  FROM employees
  WHERE department_id = dept_id;

  -- 두 번째 결과 집합
  SELECT department_id, department_name, budget
  FROM departments
  WHERE department_id = dept_id;
$$;

-- 수정된 프로시저 (RESULT SETS 2로 변경)
CREATE OR REPLACE PROCEDURE get_employee_data(dept_id INT)
LANGUAGE SQL
RESULT SETS 2  -- 올바른 선언
AS $$
  SELECT employee_id, employee_name, salary
  FROM employees
  WHERE department_id = dept_id;

  SELECT department_id, department_name, budget
  FROM departments
  WHERE department_id = dept_id;
$$;

원인 2 해결: 조건 분기 로직 리팩토링

가변적인 결과 집합 반환 대신, 단일 결과 집합으로 통합하거나 별도 프로시저로 분리합니다.

-- 문제가 있는 패턴: 조건에 따라 결과 집합 수가 달라짐
CREATE OR REPLACE PROCEDURE get_report(report_type VARCHAR)
LANGUAGE plpgsql
RESULT SETS 1
AS $$
BEGIN
  IF report_type = 'SIMPLE' THEN
    -- 결과 집합 1개 반환
    RETURN QUERY SELECT id, name FROM employees;
  ELSIF report_type = 'DETAILED' THEN
    -- 결과 집합 2개 반환 → 0100C 경고 발생!
    RETURN QUERY SELECT id, name FROM employees;
    RETURN QUERY SELECT dept_id, dept_name, budget FROM departments;
  END IF;
END;
$$;

-- 해결책 1: 최대 결과 집합 수로 RESULT SETS 선언 수정
CREATE OR REPLACE PROCEDURE get_report(report_type VARCHAR)
LANGUAGE plpgsql
RESULT SETS 2  -- 최대값으로 선언
AS $$
BEGIN
  IF report_type = 'SIMPLE' THEN
    RETURN QUERY SELECT id, name FROM employees;
    -- 두 번째 결과 집합은 빈 결과로 반환하거나 로직상 제외
  ELSIF report_type = 'DETAILED' THEN
    RETURN QUERY SELECT id, name FROM employees;
    RETURN QUERY SELECT dept_id, dept_name, budget FROM departments;
  END IF;
END;
$$;

-- 해결책 2: 프로시저를 분리하여 단일 책임 원칙 적용
CREATE OR REPLACE PROCEDURE get_simple_report()
LANGUAGE plpgsql
RESULT SETS 1
AS $$
BEGIN
  RETURN QUERY SELECT id, name FROM employees;
END;
$$;

CREATE OR REPLACE PROCEDURE get_detailed_report()
LANGUAGE plpgsql
RESULT SETS 2
AS $$
BEGIN
  RETURN QUERY SELECT id, name FROM employees;
  RETURN QUERY SELECT dept_id, dept_name, budget FROM departments;
END;
$$;

원인 3 해결: 마이그레이션 후 프로시저 점검 스크립트

마이그레이션 이후 모든 프로시저의 RESULT SETS 선언을 일괄 점검하는 방법입니다.

-- pg_proc 카탈로그를 활용해 프로시저 목록 조회
SELECT
    n.nspname AS schema_name,
    p.proname AS procedure_name,
    p.pronargs AS argument_count,
    pg_get_function_arguments(p.oid) AS arguments,
    p.prokind AS procedure_kind  -- 'p'이면 프로시저
FROM
    pg_proc p
    JOIN pg_namespace n ON p.pronamespace = n.oid
WHERE
    p.prokind = 'p'  -- 프로시저만 조회
    AND n.nspname NOT IN ('pg_catalog', 'information_schema')
ORDER BY
    n.nspname, p.proname;

-- 특정 프로시저의 정의 전체 확인
SELECT pg_get_functiondef(oid)
FROM pg_proc
WHERE proname = 'get_employee_data'
  AND prokind = 'p';

-- 경고 레벨 설정을 통해 0100C 경고를 로그로 캡처
SET client_min_messages = 'WARNING';

-- 프로시저 호출 후 경고 확인
CALL get_employee_data(10);

예방 방법

1. 프로시저 변경 시 단위 테스트 및 시그니처 검토 의무화

프로시저의 본문(body)을 수정할 때 반드시 RESULT SETS 선언도 함께 검토하도록 개발 프로세스에 포함시켜야 합니다. CI/CD 파이프라인에 프로시저 호출 후 경고 메시지를 캡처하는 테스트 스텝을 추가하고, 경고가 발생하면 배포를 차단하도록 설정합니다. 아래와 같이 pgTAP을 활용한 간단한 프로시저 테스트로 경고 발생 여부를 사전에 확인할 수 있습니다.

-- pgTAP을 활용한 프로시저 검증 예시
BEGIN;
SELECT plan(1);

-- 프로시저 호출 시 경고 없이 정상 완료되는지 확인
SELECT lives_ok(
  $$ CALL get_employee_data(10) $$,
  'get_employee_data should execute without warnings'
);

SELECT * FROM finish();
ROLLBACK;

2. 프로시저 설계 단계에서 결과 집합 수 고정화

가능하면 프로시저가 반환하는 결과 집합의 수를 설계 단계에서 고정시키고, 가변적인 결과 집합 반환이 필요한 경우에는 OUT 파라미터나 테이블 반환 함수(Table-Returning Function)를 활용합니다. 조건에 따라 다른 데이터를 반환해야 한다면, 단일 결과 집합 안에서 type_flag 컬럼 등을 추가하여 구분하는 방식이 더 안정적이고 유지보수가 쉽습니다.

-- 권장 패턴: 단일 결과 집합에 구분 컬럼 추가
CREATE OR REPLACE FUNCTION get_unified_report(report_type VARCHAR)
RETURNS TABLE(
  record_type  VARCHAR,
  id           INT,
  name         VARCHAR,
  extra_info   VARCHAR
)
LANGUAGE plpgsql
AS $$
BEGIN
  IF report_type IN ('SIMPLE', 'DETAILED') THEN
    RETURN QUERY
      SELECT 'EMPLOYEE'::VARCHAR, e.id, e.name, e.salary::VARCHAR
      FROM employees e;
  END IF;

  IF report_type = 'DETAILED' THEN
    RETURN QUERY
      SELECT 'DEPARTMENT'::VARCHAR, d.dept_id, d.dept_name, d.budget::VARCHAR
      FROM departments d;
  END IF;
END;
$$;

-- 호출 예시
SELECT * FROM get_unified_report('DETAILED');

관련 에러

  • 01000 (warning): 일반적인 SQL 경고의 부모 클래스로, 0100C는 이 카테고리에 속합니다.
  • 01P01 (deprecated_feature): 더 이상 권장되지 않는 기능을 사용할 때 발생하는 경고로, 마이그레이션 작업 시 0100C와 함께 자주 등장합니다.
  • 42P13 (invalid_function_definition): 함수 또는 프로시저 정의 자체가 유효하지 않을 때 발생하며, RESULT SETS 절의 문법 오류 시 이 에러로 이어질 수 있습니다.
  • 0A000 (feature_not_supported): 특정 PostgreSQL 버전에서 지원하지 않는 RESULT SETS 관련 기능을 사용하려 할 때 발생할 수 있습니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기