Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Stored procedures 如何在jdbc preparedStatement、CallableStatement或Spring jdbc StoredProcedure中将函数作为参数值传递?_Stored Procedures_Jdbc_Spring Jdbc - Fatal编程技术网

Stored procedures 如何在jdbc preparedStatement、CallableStatement或Spring jdbc StoredProcedure中将函数作为参数值传递?

Stored procedures 如何在jdbc preparedStatement、CallableStatement或Spring jdbc StoredProcedure中将函数作为参数值传递?,stored-procedures,jdbc,spring-jdbc,Stored Procedures,Jdbc,Spring Jdbc,我正在使用springjdbc执行一些存储过程调用,使用StoredProcedure类 某些过程将日期作为输入参数。 (我无法更改程序:它们不在我的项目范围内) 在我的业务逻辑中,我有一些关于日期的规则: 在某些情况下,对于同一进程,我可能必须提供数据库的任意日期或当前系统日期(ORACLE sysdate关键字) 调用proc时如何提供此类参数? 如果我传递“sysdate”,spring和jdbc将其解析为VARCHAR类型,调用将失败 正如我在一些文档中看到的那样,我不想首先调用数据库来

我正在使用springjdbc执行一些存储过程调用,使用StoredProcedure

某些过程将日期作为输入参数。
(我无法更改程序:它们不在我的项目范围内)

在我的业务逻辑中,我有一些关于日期的规则:
在某些情况下,对于同一进程,我可能必须提供数据库的任意日期或当前系统日期(ORACLE sysdate关键字)

调用proc时如何提供此类参数?
如果我传递“sysdate”,spring和jdbc将其解析为VARCHAR类型,调用将失败

正如我在一些文档中看到的那样,我不想首先调用数据库来检索sysdate

更一般地说,当使用所有风格的JDBC并使用“?”作为sql查询参数的占位符时,我应该如何做到这一点? 我花了一些时间试图找到一种方法来做这件事,但我没有找到答案

测试DDL:

CREATE TABLE "AAATEST" ("A_TEXT" VARCHAR2(20 BYTE), "A_DATE" DATE, "A_NUMBER" NUMBER) ;

create or replace PROCEDURE TEST_PROC ( someText in VARCHAR2, someNumber in NUMERIC, someDate in date) IS
BEGIN
    insert into AAATEST(a_text, a_number, a_date) values (someText, someNumber, someDate);
END;
Java中的测试类:

public class Test {
  public static class MyStoredProc extends StoredProcedure {
    protected MyStoredProc(DataSource ds) {
      super(ds, "test_proc");
      declareParameter(new SqlParameter("someText", Types.VARCHAR));
      declareParameter(new SqlParameter("someNumber", Types.NUMERIC));
      declareParameter(new SqlParameter("someDate", Types.DATE));
    }
  }

  public static void main(String[] args) {
    DataSource ds = new SingleConnectionDataSource("driver", "url", "username","password",false);
    MyStoredProc myStoredProc = new MyStoredProc(ds);

    //this one is ok
    myStoredProc.execute(new HashMap(){{
      put("someText", "hello world");
      put("someNumber", 3.14);
      put("someDate", new Date());
    }});

    //this one fails with 'Exception in thread "main" java.lang.IllegalArgumentException at java.sql.Date.valueOf(Date.java:140)'
    myStoredProc.execute(new HashMap(){{
      put("someText", "abc");
      put("someNumber", 123);
      put("someDate", "sysdate");
    }});            
  }
}

我认为
StoredProcedure
(或者
rdbmsooperation
总体层次结构)在这里对您没有帮助。他们关于调用字符串生成的逻辑不是以允许扩展和定制的方式编写的

我的建议是放弃
StoredProcess
,直接使用
JdbcTemplate
。这是一个有点假,但你可以完全控制通话串。然后,当您需要使用
sysdate
调用您的过程时,您只需:将其添加到调用字符串中,例如

{call TEST_PROC(?, ?, sysdate)}

您需要动态地决定是将调用字符串与
sysdate一起使用,还是不使用,并决定相应地添加哪些参数。

不幸的是,这看起来非常正确。。。我浪费了一些时间试图创建一些扩展的SimpleJDBCall类,将“?”更改为所需的函数expr。但是现在CallableStatementCreatorFactory在为db执行准备参数映射时崩溃。。。再浪费一些时间,我就能解决这个问题。。。但这将是一片混乱。。。我试图让我的老板和团队改用SpringJDBC,以避免我们目前的原始sql混乱局面。我不确定这会对春天有利。。。