Domanda

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.

È stato utile?

Soluzione

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);

Altri suggerimenti

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top