简体   繁体   English

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

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

i'm trying to call several stored functions from my java app, but whatever function i call i got the same error.我正在尝试从我的 java 应用程序中调用几个存储的函数,但是无论我调用什么 function,我都会遇到相同的错误。 For example, given this function:例如,给定这个 function:

   function insert_value (input_name varchar2) return number;

I'm trying to call it using:我正在尝试使用以下方法调用它:

   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);

I always get the same error:我总是遇到同样的错误:

    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

As you can see the name of the parameter is correct, i've already checked that my jdbc driver supports Named Parameters and i do not how i can pass indexes instead of parameters names on SimpleJdbcCall.如您所见,参数的名称是正确的,我已经检查了我的 jdbc 驱动程序是否支持命名参数,并且我不知道如何在 SimpleJdbcCall 上传递索引而不是参数名称。

Any advise?有什么建议吗? Keep in mind that i have few more complex functions which i invoke in the same way which return the same error.请记住,我有几个更复杂的函数,我以相同的方式调用它们返回相同的错误。

Try below, (there could be other way still)试试下面,(可能还有其他方法)

If I see the failure message, the input_name is not bind to the actual call.如果我看到失败消息,则 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);

OR或者

With your approach we have to specify the return parameter as in case of function the first argument is considered being the return value as a result in this case the first parameter is always omitted during the actual call.使用您的方法,我们必须指定返回参数,如 function 的情况下,第一个参数被认为是返回值,因为在这种情况下,在实际调用期间始终省略第一个参数。

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);

Firstly ensure that the object specification on the database matches to what is defined in the java app by checking from metadata tables.首先,通过检查元数据表,确保数据库上的 object 规范与 java 应用程序中定义的内容相匹配。 Execute the the query(if you don't have permissions better to get it from DBA in-charge)执行查询(如果您没有权限最好从 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'

Sample output for an object,样品 output 用于 object,

过程/函数参数的元数据

For Function you need return parameter and it should be the first argument.Modify the code to add the out parameter as below.对于 Function 您需要返回参数,它应该是第一个参数。修改代码以添加 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);

However when dealing with stored procedure it is slightly different,但是,在处理存储过程时,情况略有不同,

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));

If you have over-rided functions/procedures, then use useInParameterNames to specify the list of IN parameter names to include for a given signature.如果您有重写的函数/过程,则使用useInParameterNames指定要包含给给定签名的 IN 参数名称列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM