Reputation: 5557
I'm using Spring Jdbc to perform some stored procedures calls using the StoredProcedure class.
Some of the procedures are taking a date as an input parameter.
(I can't change the procedures: they are outside my project)
In my business logic, I have some rules about date:
in some case, for the same proc, I can have to provide an arbitrary date OR the current system date of the database (the ORACLE sysdate keyword)
How should I provide this kind of parameter when calling the proc ?
If I pass "sysdate", spring and jdbc resolve that as a VARCHAR type and the call fails.
I don't want to call the db for retrieving the sysdate first as I have seen in some documentation.
More generally, how should I do that when using all flavor of JDBC using '?' as a placeholder for sql query arguments ? I've spend some time trying to find a way to doing this, but I did not manage to find an answer.
Test 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;
Test class in 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");
}});
}
}
Upvotes: 2
Views: 2214
Reputation: 403461
I don't think StoredProcedure
(or the RdbmsOperation
hierarchy in general) are going to help you here. Their logic around the generation of the call string is not written in such a way as to allow extension and customisation.
My suggestion would be to abandon the StoredProcedure
and use JdbcTemplate
directly. It's a bit more of a faff, but you get full control over the call string. Then, when you need to call your procedure with sysdate
, you can just: add it to the call string, e.g.
{call TEST_PROC(?, ?, sysdate)}
You'd need to dynamically decide whther to use the call string with the sysdate
, or one without, and decide which parameters to add accordingly.
Upvotes: 2