Question

I made a function to one of my oracle schemas called my_schema which is called date2epoch:

create or replace function date2epoch(p_ora_date in date, p_offset in varchar2) return number is
  l_epoch_time number;
begin
  select floor((p_ora_date - to_date('1970-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS')) * 86400 -
                                  to_number(substr(tz_offset(p_offset),1,3)) * 3600) ts into l_epoch_time from dual;
  return l_epoch_time;
end;

I also made a function called date_to_et_epoch:

create or replace function date_to_et_epoch(p_ora_date in date) return number is
begin
  return date2epoch(p_ora_date, 'Europe/Tallinn');
end;

If I execute the following SQL-s with SQLPlus, they both work:

select my_schema.date_to_et_epoch(trunc(to_date('22-JAN-2014'), 'MM')) from dual;
select 1 from dual where my_schema.date_to_et_epoch(SYSDATE) > my_schema.date_to_et_epoch(trunc(to_date('22-JAN-2014'), 'MM'));

Now I make a J2EE application and want to execute those SQL-s in that application.

First this one:

select my_schema.date_to_et_epoch(trunc(?, 'MM')) from dual

So what I basically do(a bit simplified version here) is:

org.springframework.jdbc.core.namedparam.MapSqlParameterSource paramSource = new org.springframework.jdbc.core.namedparam.MapSqlParameterSource();
paramSource.addValue("mydate", new java.util.Date());
getSpringSimpleJDBCTemplate().query("select my_schema.date_to_et_epoch(trunc(:mydate, 'MM')) from dual", new MyRowMapper(), paramSource);

This works great.

But if I try the second one:

org.springframework.jdbc.core.namedparam.MapSqlParameterSource paramSource = new org.springframework.jdbc.core.namedparam.MapSqlParameterSource();
paramSource.addValue("mydate", new java.util.Date());
getSpringSimpleJDBCTemplate().query("select 1 from dual where my_schema.date_to_et_epoch(SYSDATE) > my_schema.date_to_et_epoch(trunc(:mydate, 'MM'))", new MyRowMapper(), paramSource);

I get an exception:

org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [select 1 from dual where my_schema.date_to_et_epoch(SYSDATE) > my_schema.date_to_et_epoch(trunc(?, 'MM'))]; nested exception is java.sql.SQLException: ORA-06553: PLS-306: wrong number or types of arguments in call to 'DATE_TO_ET_EPOCH'.

I can't understand why is that. I assume that this has got soemthing to do how Spring-s JDBC template or Oracle Driver handles mapping java Date objects as parameters differently than to_date in SQL. But still, is there something that I am doing conceptually wrong or is there something I could do to fix this? I would prefer to fix this on Java side not the SQL side as the SQL is composed by third party and may allways change during time.

Was it helpful?

Solution

As Pavel Horak suggested in a comment under the question adding the parameter data type explicitly in Java code saved the day.

Example of a code that works in each way:

org.springframework.jdbc.core.namedparam.MapSqlParameterSource paramSource = new org.springframework.jdbc.core.namedparam.MapSqlParameterSource();
paramSource.addValue("mydate", new java.util.Date(), java.sql.Types.DATE);
getSpringSimpleJDBCTemplate().query("select 1 from dual where my_schema.date_to_et_epoch(SYSDATE) > my_schema.date_to_et_epoch(trunc(:mydate, 'MM'))", new MyRowMapper(), paramSource);

OTHER TIPS

if you look at the query that is causing the exception:

 org.springframework.jdbc.core.namedparam.MapSqlParameterSource paramSource = new org.springframework.jdbc.core.namedparam.MapSqlParameterSource();
 paramSource.addValue("myDate", new java.util.Date());     
 getSpringSimpleJDBCTemplate().query("select 1 from dual where my_schema.date_to_et_epoch(SYSDATE) > my_schema.date_to_et_epoch(trunc(:mydate, 'MM'))", new MyRowMapper(), paramSource);

The parameter map binds myDate, but in your query you have :mydate ... there is a difference in case

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top