javaoracle-databasejdbcplsqlsimplejdbccall

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. For example, given this 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.

Any advise? Keep in mind that i have few more complex functions which i invoke in the same way which return the same error.


Solution

  • Firstly ensure that the object specification on the database matches to what is defined in the java app by checking from metadata tables. Execute the the query(if you don't have permissions better to get it from DBA in-charge)

    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,

    meta data for procedure/function arguments

    For Function you need return parameter and it should be the first argument.Modify the code to add the out parameter as below.

    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.