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

Quarkus JPA调用PostgreSQL存储过程提示需使用CALL报错如何解决

问题解决方案

核心触发原因

你遇到的报错和pgjdbc版本无关,核心原因是无返回值的PostgreSQL存储过程要求必须用CALL语法调用,而JPA默认的存储过程调用逻辑会生成SELECT * FROM 存储过程名(参数)的不符合要求的语法,就算驱动版本包含修复,没有正确配置或调整调用方式也会触发报错。

具体修复步骤

你可以任选以下任意一种方案解决问题:

  • 方案一:改用原生SQL直接调用(最稳妥,适配无返回值场景)
    直接通过EntityManager创建原生查询执行CALL语句,示例代码如下:

    // 注入EntityManager
    @PersistenceContext
    EntityManager entityManager;
    
    // 调用存储过程逻辑
    entityManager.createNativeQuery("CALL generate_sums(?1, ?2, ?3)")
      .setParameter(1, 第一个Long类型入参)
      .setParameter(2, 第二个Long类型入参)
      .setParameter(3, 第三个Long类型入参)
      .executeUpdate();
    
  • 方案二:调整JPA存储过程调用逻辑
    如果你要继续使用StoredProcedureQuery API,不要省略执行方法的配置,无返回值场景必须调用executeUpdate()而不是通用的execute(),示例代码如下:

    StoredProcedureQuery procedureQuery = entityManager.createStoredProcedureQuery("generate_sums");
    // 注册入参
    procedureQuery.registerStoredProcedureParameter(1, Long.class, ParameterMode.IN);
    procedureQuery.registerStoredProcedureParameter(2, Long.class, ParameterMode.IN);
    procedureQuery.registerStoredProcedureParameter(3, Long.class, ParameterMode.IN);
    // 赋值参数
    procedureQuery.setParameter(1, 第一个Long类型入参);
    procedureQuery.setParameter(2, 第二个Long类型入参);
    procedureQuery.setParameter(3, 第三个Long类型入参);
    // 无返回值必须用executeUpdate,不要使用execute()
    procedureQuery.executeUpdate();
    
  • 方案三:添加驱动适配配置
    在项目的application.properties配置文件中添加pgjdbc专属参数,驱动会自动识别无返回值的存储过程,自动切换为CALL语法:

    quarkus.datasource.jdbc.additional-jdbc-properties.escapeSyntaxCallMode=callIfNoReturn
    

验证逻辑

调整配置或代码后重新触发存储过程调用,确认不会抛出org.postgresql.util.PSQLException异常,同时存储过程对应的INSERT SELECT逻辑正常执行,目标表数据写入符合预期即可。

内容的提问来源于stack exchange,提问作者pyros77

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 08:18:02