You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL自定义函数SpringBoot调用报错:无匹配函数及参数类型

问题详情

在PostgreSQL数据库中定义了schema1.ven_totais_nfes函数,参数类型为date、date、text[],直接执行SQL脚本可正常返回结果;但在SpringBoot后端通过EntityManager调用该函数时,出现错误:ERROR: function ven_totais_nfes(unknown, unknown, uuid) does not exist,提示无匹配函数及参数类型,需显式类型转换。


PostgreSQL函数定义

CREATE OR REPLACE FUNCTION schema1.ven_totais_nfes(data_inicial date, data_final date, setor_usuario text[])
 RETURNS TABLE(status character varying, quantidade bigint, valor numeric)
 LANGUAGE plpgsql
 SET search_path TO 'schema1', '$user', 'public'
AS $function$
 declare
    item record;
begin
    [...] 
$function$;

手动执行的SQL脚本

select * from ven_totais_nfes('2022-12-01', '2022-12-31', array['aef4786e-7d99-4fdc-a20a-4da11c168eb2'])

SpringBoot调用代码

public List<NFeTotaisViewDto> findTotais(Date dataInicial, Date dataFinal, List<UUID> setorUsuario) {
    Query query = entityManager.createNativeQuery("select * from ven_totais_nfes(:dataInicial, :dataFinal, :setorUsuario)");
    query.setParameter("dataInicial", dataInicial);
    query.setParameter("dataFinal", dataFinal);
    query.setParameter("setorUsuario", setorUsuario);
    // 省略后续映射及返回逻辑
}

错误原因

  • 参数类型不匹配:函数第三个参数为text[],但SpringBoot传入的List<UUID>会被JDBC驱动映射为PostgreSQL的uuid类型,最终参数类型变为uuid[],与函数定义的text[]不匹配。
  • 日期参数隐式识别问题:手动执行时日期字符串会被PostgreSQL自动转换为date类型,但通过EntityManager传入Date对象时,可能被识别为unknown类型,未正确映射到date。

解决方法

方法1:SQL中显式转换参数类型

修改NativeQuery的SQL语句,对参数进行强制类型转换:

public List<NFeTotaisViewDto> findTotais(Date dataInicial, Date dataFinal, List<UUID> setorUsuario) {
    String sql = "select * from ven_totais_nfes(" +
        ":dataInicial::date, " +
        ":dataFinal::date, " +
        ":setorUsuario::text[])";
    Query query = entityManager.createNativeQuery(sql);
    query.setParameter("dataInicial", dataInicial);
    query.setParameter("dataFinal", dataFinal);
    query.setParameter("setorUsuario", setorUsuario);
    // 后续逻辑
}

方法2:将UUID列表转换为字符串列表传入

在Java代码中把List<UUID>转为List<String>,确保传入的是字符串数组,匹配函数的text[]参数,同时显式指定日期参数类型:

public List<NFeTotaisViewDto> findTotais(Date dataInicial, Date dataFinal, List<UUID> setorUsuario) {
    List<String> setorUsuarioStr = setorUsuario.stream()
        .map(UUID::toString)
        .collect(Collectors.toList());
    Query query = entityManager.createNativeQuery("select * from ven_totais_nfes(:dataInicial, :dataFinal, :setorUsuario)");
    query.setParameter("dataInicial", dataInicial, TemporalType.DATE);
    query.setParameter("dataFinal", dataFinal, TemporalType.DATE);
    query.setParameter("setorUsuario", setorUsuarioStr);
    // 后续逻辑
}

方法3:修改PostgreSQL函数参数类型(可选)

如果业务允许,将函数第三个参数改为uuid[],直接匹配传入的UUID列表:

CREATE OR REPLACE FUNCTION schema1.ven_totais_nfes(data_inicial date, data_final date, setor_usuario uuid[])
 RETURNS TABLE(status character varying, quantidade bigint, valor numeric)
 LANGUAGE plpgsql
 SET search_path TO 'schema1', '$user', 'public'
AS $function$
 declare
    item record;
begin
    [...] 
$function$;

注意:修改后手动执行SQL时,需传入uuid[]类型,例如:array['aef4786e-7d99-4fdc-a20a-4da11c168eb2']::uuid[]


内容的提问来源于stack exchange,提问作者Altair Todescatto F

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 17:55:18