永久性 ORA-06550 错误,使用 jdbc 从 java 应用程序调用存储函数

Permanent ORA-06550 error, calling stored function from java application using jdbc

我正在尝试从我的 java 应用程序调用几个存储函数,但无论我调用什么函数,我都会遇到同样的错误。 例如,给出这个函数:

   function insert_value (input_name varchar2) return number;

我正在尝试使用以下方式调用它:

   JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
   SimpleJdbcCall call= new SimpleJdbcCall(jdbcTemplate)
                    .withCatalogName("MY_PACKAGE_NAME")
                    .withFunctionName("insert_value")
                    .withoutProcedureColumnMetaDataAccess()
                    .declareParameters(
                            new SqlParameter("input_name", Types.VARCHAR));
   SqlParameterSource parameterMap = new MapSqlParameterSource()
                 .addValue("input_name", "John Doe");
   int idNumber = call.executeFunction(Integer.class,parameterMap);

我总是得到同样的错误:

    java.sql.SQLException: ORA-06550: line 1, column 7:
    PLS-00306: wrong number or types of arguments in call to 'INSERT_VALUE'
    ORA-06550: line 1, column 7:
    PL/SQL: Statement ignored

如您所见,参数名称是正确的,我已经检查过我的 jdbc 驱动程序支持命名参数,但我不知道如何在 SimpleJdbcCall 上传递索引而不是参数名称。

有什么建议吗?请记住,我有几个更复杂的函数,我以相同的方式调用这些函数 return 同样的错误。

试试下面,(可能还有其他方法)

如果我看到失败消息,则 input_name 未绑定到实际调用。

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        SimpleJdbcCall call = new SimpleJdbcCall(jdbcTemplate).withCatalogName("MY_PACKAGE_NAME")
                .withFunctionName("insert_value");

        SqlParameterSource parameterMap = new MapSqlParameterSource().addValue("input_name", "John Doe",
                Types.VARCHAR);

        BigDecimal idNumber = call.executeFunction(BigDecimal.class, parameterMap);

使用您的方法,我们必须指定 return 参数,因为在函数的情况下,第一个参数被认为是 return 值,因此在这种情况下,第一个参数始终被省略实际调用。

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        SimpleJdbcCall call = new SimpleJdbcCall(jdbcTemplate).withCatalogName("MY_PACKAGE_NAME")
                .withFunctionName("insert_value").withoutProcedureColumnMetaDataAccess().declareParameters(
                        new SqlOutParameter("return", Types.INTEGER), new SqlParameter("input_name", Types.VARCHAR));

        SqlParameterSource parameterMap = new MapSqlParameterSource().addValue((String) "input_name", "John Doe",
                Types.VARCHAR);

        Integer idNumber = call.executeFunction(Integer.class, parameterMap);

首先通过检查元数据表确保数据库中的对象规范与 java 应用程序中定义的相匹配。 执行查询(如果您没有权限最好从负责的 DBA 那里获取)

select object_name,argument_name,position,data_type,data_length,in_out 
from   user_arguments
where  OBJECT_NAME ='MY_PROCEDURE_OR_FUNCTION' 
and    Package_name='MY_PACKAGE'

对象的示例输出,

对于 Function 你需要 return 参数,它应该是第一个 argument.Modify 添加 out 参数的代码,如下所示。

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
   SimpleJdbcCall call= new SimpleJdbcCall(jdbcTemplate)
                    .withCatalogName("MY_PACKAGE_NAME")
                    .withFunctionName("insert_value")
                    .withoutProcedureColumnMetaDataAccess()
                    .declareParameters(new SqlOutParameter("return",Types.INTEGER),
                            new SqlParameter("input_name", Types.VARCHAR));
   SqlParameterSource parameterMap = new MapSqlParameterSource()
                 .addValue("input_name", "John Doe");
   int idNumber = call.executeFunction(Integer.class,parameterMap);

但是在处理存储过程时,情况略有不同,

SimpleJdbcCall jdbcCall = new SimpleJdbcCall(springTemplate) 
.withCatalogName("PACKAGE_NAME").withProcedureName("PROCEDURE_NAME")
.withReturnValue().withoutProcedureColumnMetaDataAccess()
.declareParameters(new SqlParameter("INPUT_PARAMETER", Types.VARCHAR),
new SqlOutParameter("OUTPUT_PARAMETER_NAME", Types.VARCHAR));

如果您已覆盖 functions/procedures,则使用 useInParameterNames 指定要包含给定签名的 IN 参数名称列表。