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

使用JPA Repository调用Oracle函数遇ORA-06550参数错误

问题分析

你遇到的PLS-00306错误,核心原因是用JPA的@Procedure注解调用Oracle函数的方式错误:

  • 你的Storicizza是带返回值的Oracle函数,它通过RETURN语句返回结果,本身没有输出参数;
  • 但@Procedure注解是为调用存储过程设计的,JPA会自动把你指定的outputParameterName当成一个额外的输出参数传递给函数,导致生成的SQL多了一个参数(NIDACCREDTARGET=>:5),和函数定义的5个输入参数不匹配,触发参数数量错误。

从生成的SQL能明确问题:

BEGIN PCK_STO.Storicizza(PIDACCRED=>:0,PUSER=>:1,PCOGNOMENOME=>:2,PCODICEFISCALE=>:3,PVERSIONE=>:4,NIDACCREDTARGET=>:5); END;

函数定义仅需5个输入参数,这里却传递了6个,自然触发参数不匹配报错。

解决方案

Oracle函数的正确调用方式是通过SELECT语句执行,而非存储过程的CALL语法,推荐以下两种实现方式:

方法1:使用@NamedNativeQuery

在对应的实体类(比如Acc0000Accreditamenti)上定义原生查询:

@Entity
@NamedNativeQuery(
    name = "Acc0000Accreditamenti.storicizza",
    query = "SELECT PCK_STO.Storicizza(:pIdAccred, :pUser, :pCognomeNome, :pCodiceFiscale, :pVersione) FROM DUAL",
    resultClass = Long.class
)
public class Acc0000Accreditamenti {
    // 实体类字段定义...
}

然后在Repository中定义对应方法:

public interface Acc0000AccreditamentiRepository extends JpaRepository<Acc0000Accreditamenti, Long> {
    @Query(name = "Acc0000Accreditamenti.storicizza", nativeQuery = true)
    Long storicizza(@Param("pIdAccred") Long idAccreditamento,
                    @Param("pUser") String user,
                    @Param("pCognomeNome") String nomeCognome,
                    @Param("pCodiceFiscale") String codFiscale,
                    @Param("pVersione") Long versione);
}

方法2:直接用@Query写原生SQL

如果不想在实体类上加注解,也可以直接在Repository方法上编写原生查询:

public interface Acc0000AccreditamentiRepository extends JpaRepository<Acc0000Accreditamenti, Long> {
    @Query(value = "SELECT PCK_STO.Storicizza(:pIdAccred, :pUser, :pCognomeNome, :pCodiceFiscale, :pVersione) FROM DUAL", nativeQuery = true)
    Long storicizza(@Param("pIdAccred") Long idAccreditamento,
                    @Param("pUser") String user,
                    @Param("pCognomeNome") String nomeCognome,
                    @Param("pCodiceFiscale") String codFiscale,
                    @Param("pVersione") Long versione);
}
额外检查点
  • 确保JPA传递的参数类型和Oracle函数的参数类型完全匹配:比如acc0000_accreditamenti.id%TYPE如果是NUMBER(10),用Long没问题;字符串类型要对应Oracle的VARCHAR2;
  • 确认数据库用户拥有调用PCK_STO.Storicizza函数的权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 18:46:29