当前位置: 首页 > 知识库问答 >
问题:

使用JDBC模板从Java调用oracle存储过程时面临的问题

唐照
2023-03-14

“stack_trace”:“org.springframework.jdbc.uncategorizedsqlexception:CallableStatementCallback;SQL[{call post_cycle_tfo_stat_pkg.insert_cycle_status(?,?,?,?)}]得SQLException未分类;SQL状态[99999];错误代码[17004];无效列类型:16;嵌套异常为java.SQL.SQLException:无效列类型:16\r\n\tat\tat org.springframework.jdbc.core.simple.abstractjdbccall.execute(abstractjdbccall.java:412)\r\n\tat org.springframework.jdbccall.doexecute(abstractjdbccall.java:372)\r\n\tat org.springframework.jdbc.core.simple.simplejdbccall.java:198)\r\n\tat

我的过程语法是:

PROCEDURE insert_cycle_status (SETTLEMENT_DATE_MANUAL   IN     DATE,
                                  DEBUG_FLAG               IN OUT BOOLEAN,
                                  ERROR_INFO                  OUT VARCHAR2,
                                  RESULT                      OUT BOOLEAN);

我的Java代码如下:

SimpleJdbcCall call = new SimpleJdbcCall(jdbcTemplate)
                            .withoutProcedureColumnMetaDataAccess()
                            .withProcedureName(CYCLE_EVENT_STATUS_PROCEDURE)
                            .declareParameters(new SqlParameter("SETTLEMENT_DATE_MANUAL", Types.DATE))
                            .declareParameters(new SqlParameter("DEBUG_FLAG", Types.BOOLEAN))
                            .declareParameters(new SqlOutParameter("ERROR_INFO", Types.VARCHAR))
                            .declareParameters(new SqlOutParameter("RESULT", Types.BOOLEAN));
            
            SqlParameterSource in = new MapSqlParameterSource()
                            .addValue("SETTLEMENT_DATE_MANUAL", null)
                            .addValue("DEBUG_FLAG", 1);
            
            Map<String, Object> result = call.execute(in);

有谁能分享一些关于这个问题的建议,这将是非常有帮助的。谢谢!预先

共有1个答案

阙博容
2023-03-14

这里的主要问题是Oracle JDBC驱动程序不支持将布尔函数传递到存储过程中

您可以使用一个简单的技巧来传递in布尔参数,如另一个答案中所述,但这对inout参数不起作用。

因此,作为一种解决办法,您必须使用INT参数而不是布尔参数包装存储过程

-- wrapper procedure 
create or replace PROCEDURE insert_cycle_status2 (SETTLEMENT_DATE_MANUAL   IN     DATE,
                                  DEBUG_FLAG               IN OUT INT, /* Wrap BOOLEAN with INT */
                                  ERROR_INFO                  OUT VARCHAR2,
                                  RESULT                      OUT INT) as
 v_DEBUG_FLAG BOOLEAN := (DEBUG_FLAG != 0);
 v_RESULT BOOLEAN := (RESULT != 0);
begin
  insert_cycle_status(SETTLEMENT_DATE_MANUAL,v_DEBUG_FLAG, ERROR_INFO, v_RESULT);
  if v_RESULT  THEN 
     RESULT := 1;
  else
    RESULT := 0;
  end if;
  if v_DEBUG_FLAG  THEN 
     DEBUG_FLAG := 1;
  else
    DEBUG_FLAG := 0;
  end if;         
end;   
/

通过将types.boolean替换为types.integer,您的代码将会很简单

Oracle 12.2的更新

如图所示,Oracle12.2支持PLSQL_Boolean的本机绑定。

// works in Oracle Release 12.2+
stmt = con.prepareCall("{ call insert_cycle_status(?,?,?,?)}") 
stmt.setDate(1, java.sql.Date.valueOf("2020-11-21"));
stmt.setObject(2,true,oracle.jdbc.OracleTypes.PLSQL_BOOLEAN)  /* BOOLEAN parameter */
stmt.registerOutParameter(2,oracle.jdbc.OracleTypes.PLSQL_BOOLEAN)
stmt.registerOutParameter(3,Types.VARCHAR)
stmt.registerOutParameter(4,oracle.jdbc.OracleTypes.PLSQL_BOOLEAN)
stmt.execute()
 类似资料:
  • 问题内容: Spring JDBC模板调用存储过程的正确方法是什么? 说,我有一个同时声明和参数的存储过程,如下所示: 我遇到了一些基于方法,我们必须显式地注册和参数化。在课堂上考虑以下方法: 当然,我知道我可以这样使用它: 我已经在实现中注册它们的目的是什么?换句话说,为什么我需要传递一个csc春天可以简单地在内部完成的事情?基本上,我不能传递其中一个而不是两个吗? 或者,是否有比我到目前为止遇

  • 我有一个非常复杂的oracle存储过程,它搜索和检索一些数据。该过程返回一个输出参数-oracle游标。我通过JDBC执行过程: 问题是,查询有时会花费相当长的时间(几分钟),我希望用户能够通过单击按钮随时取消查询。我引用了stmt对象,但不幸的是(从其他线程)调用stmt.cancel()没有效果。 另一方面,当我将CallableStatement sql更改为以下查询时: 在调用stmt.c

  • 主要内容:创建CallableStatement对象,关闭CallableStatement对象,JDBC SQL转义语法在讨论JDBC Statement教程文章时,我们已经学习了如何在JDBC中使用存储过程。 本教程文章与该部分类似,但它将讲解演示有关JDBC SQL转义语法的其他信息。 就像对象创建和对象一样,它可使用同样的方式创建对象,该对象将用于执行对数据库存储过程的调用。 创建CallableStatement对象 假设需要执行以下Oracle存储过程 - 注意:上面的存储过程是为O

  • 我创建了一个存储过程,如下所示: //mysql中的存储过程 并且我正在调用Java中的存储过程,如下所示: //使用JDBC调用存储过程 但它显示了一个编译时异常,如下所示: CAN在参数中为存储的函数调用的返回值设置。

  • 我在Oracle中有一个存储过程,如下所示。 我正在从Java调用该过程。我的密码是, 即使我正在获取记录,值也是空的。这意味着如果输出为2行,则while条件执行并打印为空。在SQL Developer中,它工作得很好。提前道谢。

  • 作为重构的一部分,我正在尝试将数据库调用更改为使用Spring 4.1.0。释放以处理连接和异常,并允许在函数和类之间传递结果集。 我的MS SQL Server存储过程调用工作正常,但当我尝试执行Oracle存储过程时,收到以下错误消息: 我通过编写两个非常简单的写入测试表的存储过程来简化问题:一个接受参数并写入,另一个不接受参数,只写入硬编码值。这些过程位于INV模式中,这是我的数据源配置使用