【问题标题】:Spring: Unable to determine the correct call signature - multiple procedures/functions/signaturesSpring:无法确定正确的调用签名 - 多个过程/函数/签名
【发布时间】:2018-05-25 02:12:32
【问题描述】:

我正在尝试从 Oracle 存储过程中获取数据。问题是在我们的数据库中有一个函数和一个过程具有相同的名称和相同的参数。

当我尝试调用它时:

@Autowired
    public void setDataSource (@Qualifier("dataSource") DataSource dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.setResultsMapCaseInsensitive(true);
        this.functionGetSomeCode = new SimpleJdbcCall(jdbcTemplate)
                .declareParameters(new SqlOutParameter("RETURN", OracleTypes.NUMBER))
                .withFunctionName("get_some_code").withSchemaName("XXX").withCatalogName("some_pkg");
    }

    public Integer getSomeCode (String incoming) {
        SqlParameterSource incomingParameters = new MapSqlParameterSource().addValue("incoming", incoming);
        return functionGetSomeCode.executeFunction(Integer.class, incomingParameters);
    }

我得到一个例外:

springframework.dao.InvalidDataAccessApiUsageException: Unable to determine the correct call signature - multiple procedures/functions/signatures

有没有办法在不要求 DBA 将函数/过程重命名为其他名称的情况下处理这种情况?

【问题讨论】:

    标签: java spring oracle stored-procedures


    【解决方案1】:

    我已经能够调用具有相同名称的函数和过程,但它并不总是有效。 在您的示例中,您似乎没有声明输入参数。尝试使用与包声明尽可能匹配的类型来声明输入和输出参数。如果这仍然不起作用,您可以尝试关闭 ProcedureColumnMetaDataAccess,但请务必进行测试。

    这是一个例子:

    protected SimpleJdbcCall buildJdbcCall(JdbcTemplate jdbcTemplate) {
        SimpleJdbcCall call = new SimpleJdbcCall(jdbcTemplate)
                .withSchemaName(schema)
                .withCatalogName(catalog)
                .withFunctionName(functionName) 
                // can use withProcedureName(procedureName) for procedures 
                //.withReturnValue()
                //  .withoutProcedureColumnMetaDataAccess()  // may need this
                .declareParameters(buildSqlParameters());
        return call;
    }
    
    public SqlParameter[] buildSqlParameters() {
        return new SqlParameter[]{
            new SqlParameter("p_id", Types.VARCHAR),
            new SqlParameter("p_office_id", Types.VARCHAR),
            new SqlOutParameter("l_clob", Types.CLOB)
        };
    }
    

    【讨论】:

    • 感谢您的输入,但如果您仔细研究代码,我的参数(输入和输出)会被声明。
    • 您将“传入”参数传递给 executeFunction 调用,而没有在 declareParameters 数组中声明它。
    【解决方案2】:

    如果您没有返回变量,下面的代码可以提供帮助。我遇到了同样的问题,我的代码在没有声明输出参数的情况下工作,因为函数没有输出参数。我通过将 out 参数声明为 return 解决了这个问题。代码如下。

    SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate.getDataSource()).withCatalogName("PACKAGE_NAME")
                    .withFunctionName("MY_FUNCTION_NAME").withoutProcedureColumnMetaDataAccess().declareParameters(
                            new SqlOutParameter("RETURN", Types.TIMESTAMP),
                            new SqlParameter("XYX_Y", Types.DATE),
                            new SqlParameter("HH_HDU", Types.VARCHAR)
                            );
            jdbcCall.compile();
    
            MapSqlParameterSource in = new MapSqlParameterSource();
            in.addValue("XYX_Y", myDate);
            in.addValue("HH_HDU", "PQR");
            java.sql.Timestamp date =  jdbcCall.executeFunction(java.sql.Timestamp.class, in);
    
    

    【讨论】:

      【解决方案3】:

      我也面临同样的问题。我有 2 个同名处理器和一个不同的参数“lang_code_in”。看起来问题只是由于这个问题,它是由于 Spring/Spring 引导应用程序而出现的。所以我在“.withoutProcedureColumnMetaDataAccess()”之后添加了。

          final SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(dataSource).withCatalogName(catalogName)
                  .withProcedureName(procedureName)
                  .withoutProcedureColumnMetaDataAccess().
                  .declareParameters(buildPullOrderSqlParameters());
      

      但在此之后它开始给出以下错误: org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback;错误的 SQL 语法 [{call NPIADM.CCM_JIGSAW_TEMPLATE_PKG.GET_UPC_XML_CONTENT(?, ?, ?)}];嵌套异常是 java.sql.SQLException:ORA-06550:第 1 行,第 7 列: PLS-00306:调用“GET_UPC_XML_CONTENT”时参数的数量或类型错误 ORA-06550:第 1 行,第 7 列: PL/SQL:语句被忽略

      然后我添加了所有输入和输出参数 declareParameters() 对象,如下所示,它开始正常工作。下面的代码有 P_ORDER_NUMBER_I 是 IN 参数和 p_err_msg_o 是 out 参数

      public SqlParameter[] buildPullOrderSqlParameters() {
          return new SqlParameter[]{
                  new SqlParameter("P_ORDER_NUMBER_I", Types.VARCHAR),
                  new SqlOutParameter("p_err_msg_o", Types.VARCHAR)
          };
      }
      

      【讨论】:

        猜你喜欢
        • 2013-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-21
        相关资源
        最近更新 更多