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

54023
2026년 09월 20일 | DBMS Error 가이드

이 글에서 다루는 내용

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

54023 too many arguments 는?

PostgreSQL 에러 코드 54023, “too many arguments”는 함수나 프로시저를 호출할 때 해당 함수가 허용하는 것보다 더 많은 인수(argument)를 전달했을 때 발생하는 에러입니다. 이 에러는 주로 사용자 정의 함수(UDF), 내장 함수, 또는 저장 프로시저를 잘못된 시그니처로 호출할 때 나타납니다. PostgreSQL의 함수 오버로딩 특성상 인수 개수와 타입이 정확히 일치하는 함수를 찾지 못하면 이 에러가 발생할 수 있습니다.

주요 발생 원인

  • 함수 시그니처와 맞지 않는 인수 개수 전달

가장 흔한 원인으로, 함수 정의에 명시된 매개변수 수보다 더 많은 값을 전달할 때 발생합니다. 예를 들어, 두 개의 인수를 받는 함수에 세 개 이상의 인수를 넘기는 경우가 대표적입니다. 특히 애플리케이션 코드를 유지보수하면서 함수 시그니처를 변경했는데 호출부를 업데이트하지 않았을 때 자주 발생합니다.

  • FORMAT() 또는 문자열 함수에 잘못된 플레이스홀더 수 사용

format() 함수를 사용할 때 포맷 문자열 내의 %s, %I, %L 등의 플레이스홀더 수와 실제 제공하는 인수 수가 불일치할 때 이 에러가 발생합니다. 반대로 너무 많은 인수를 제공하거나, 포맷 문자열에서 플레이스홀더를 누락한 경우 모두 문제가 됩니다. 동적 SQL을 자주 사용하는 환경에서 특히 주의가 필요합니다.

  • PL/pgSQL 내부에서 EXECUTE 또는 동적 함수 호출 시 인수 오류

PL/pgSQL 블록 내에서 EXECUTE 문이나 동적으로 함수를 호출할 때, 런타임에 구성된 인수 목록이 함수의 실제 매개변수 수와 맞지 않으면 에러가 발생합니다. 특히 배열이나 반복문을 이용해 동적으로 인수를 구성할 때 논리 오류가 포함될 가능성이 높습니다. 이 경우는 정적 분석으로 잡기 어려워 런타임에서야 에러가 드러나는 경우가 많습니다.

해결 방법

원인 1: 함수 인수 개수 불일치 해결

먼저 함수의 정의를 확인하고 호출부를 수정합니다.

-- 잘못된 호출 예시 (2개 인수를 받는 함수에 3개 전달)
CREATE OR REPLACE FUNCTION add_numbers(a INTEGER, b INTEGER)
RETURNS INTEGER AS $$
BEGIN
    RETURN a + b;
END;
$$ LANGUAGE plpgsql;

-- 에러 발생: too many arguments
SELECT add_numbers(1, 2, 3);

-- 올바른 호출
SELECT add_numbers(1, 2);

-- 함수 시그니처 확인 방법
SELECT proname, pronargs, proargtypes::text
FROM pg_proc
WHERE proname = 'add_numbers';

-- 더 자세한 인수 정보 확인
SELECT proname, pg_get_function_arguments(oid) AS arguments
FROM pg_proc
WHERE proname = 'add_numbers';

원인 2: FORMAT() 함수 플레이스홀더 불일치 해결

-- 잘못된 예시: 플레이스홀더는 1개인데 인수는 2개
SELECT format('Hello, %s', 'World', 'Extra');
-- ERROR: too many arguments for format()

-- 올바른 예시: 플레이스홀더와 인수 수 일치
SELECT format('Hello, %s! You are number %s.', 'World', 1);

-- 여러 플레이스홀더를 사용하는 동적 SQL 예시
DO $$
DECLARE
    v_table TEXT := 'employees';
    v_column TEXT := 'salary';
    v_value NUMERIC := 5000;
    v_sql TEXT;
BEGIN
    -- 올바른 format() 사용 (플레이스홀더 3개, 인수 3개)
    v_sql := format(
        'UPDATE %I SET %I = %L WHERE department_id = 10',
        v_table,
        v_column,
        v_value
    );
    RAISE NOTICE 'Generated SQL: %', v_sql;
    EXECUTE v_sql;
END;
$$;

원인 3: PL/pgSQL 동적 호출 시 인수 오류 해결

-- 잘못된 동적 함수 호출 예시
CREATE OR REPLACE FUNCTION dynamic_call_example()
RETURNS VOID AS $$
DECLARE
    v_args TEXT[] := ARRAY['arg1', 'arg2', 'arg3']; -- 인수가 너무 많음
BEGIN
    -- 이 함수는 2개의 인수만 받음
    EXECUTE format('SELECT my_two_arg_function(%s)', array_to_string(v_args, ','));
END;
$$ LANGUAGE plpgsql;

-- 올바른 방법: 인수 배열 크기를 함수 시그니처에 맞게 조정
CREATE OR REPLACE FUNCTION dynamic_call_safe()
RETURNS VOID AS $$
DECLARE
    v_func_name TEXT := 'add_numbers';
    v_arg1 INTEGER := 10;
    v_arg2 INTEGER := 20;
    v_result INTEGER;
BEGIN
    -- USING 절을 활용한 안전한 동적 실행
    EXECUTE format('SELECT %I($1, $2)', v_func_name)
    INTO v_result
    USING v_arg1, v_arg2;

    RAISE NOTICE '결과: %', v_result;
END;
$$ LANGUAGE plpgsql;

SELECT dynamic_call_safe();

-- 함수의 인수 개수를 먼저 확인하고 동적 호출하는 패턴
CREATE OR REPLACE FUNCTION safe_dynamic_function_call(
    p_func_name TEXT,
    p_args ANYARRAY
)
RETURNS TEXT AS $$
DECLARE
    v_expected_args INTEGER;
    v_provided_args INTEGER;
BEGIN
    -- 함수의 예상 인수 개수 조회
    SELECT pronargs INTO v_expected_args
    FROM pg_proc
    WHERE proname = p_func_name
    LIMIT 1;

    v_provided_args := array_length(p_args, 1);

    IF v_expected_args != v_provided_args THEN
        RAISE EXCEPTION '함수 % 는 % 개의 인수를 필요로 하지만 % 개가 제공되었습니다.',
            p_func_name, v_expected_args, v_provided_args;
    END IF;

    RETURN '인수 개수 검증 통과';
END;
$$ LANGUAGE plpgsql;

예방 방법

  • 함수 변경 시 반드시 호출부 전수 조사 및 회귀 테스트 수행

함수 시그니처를 변경할 때는 pg_proc 카탈로그와 애플리케이션 코드 전체를 검색하여 해당 함수를 호출하는 모든 지점을 파악해야 합니다. CI/CD 파이프라인에 함수 시그니처 변경을 자동으로 감지하는 테스트를 추가하고, 변경 전후 인수 목록을 문서화하는 습관을 들이는 것이 좋습니다. 아래 쿼리로 특정 함수를 참조하는 다른 함수나 뷰를 사전에 확인할 수 있습니다.

“`sql

— 특정 함수를 참조하는 의존성 확인

SELECT DISTINCT

deptype,

classid::regclass,

objid::regprocedure

FROM pg_depend

WHERE refobjid = ‘add_numbers(integer, integer)’::regprocedure;

“`

  • format() 함수 사용 시 플레이스홀더와 인수를 명시적으로 매핑하여 검토

동적 SQL을 생성할 때는 format() 함수의 플레이스홀더 수와 인수 수가 일치하는지 코드 리뷰 체크리스트에 항목으로 추가하세요. 가능하면 USING 절을 활용한 파라미터 바인딩 방식을 사용하여 SQL 인젝션 방지와 동시에 인수 불일치 오류를 줄이는 것이 실무에서 권장되는 Best Practice입니다.

관련 에러

  • 42883 (undefined_function): 주어진 인수 타입에 맞는 함수를 찾을 수 없을 때 발생하며, 54023과 함께 함수 호출 관련 에러 중 가장 자주 마주치는 에러입니다.
  • 42P13 (invalid_function_definition): 함수 정의 자체가 잘못된 경우 발생하며, 함수를 생성하거나 수정할 때 나타납니다.
  • 54001 (statement_too_complex): 함수 인수 과다와는 다르지만, 동일하게 54xxx 클래스(프로그램 제한 초과)에 속하는 관련 에러입니다.
  • 22023 (invalid_parameter_value): 인수 개수는 맞지만 값 자체가 유효하지 않을 때 발생하는 에러로, 함수 호출 문제 진단 시 함께 고려해야 합니다.
DBMS 에러 코드 시리즈

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

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

댓글 남기기