Function "TO_DATE" not found in H2 database - java

I have a SQL statement and trying execute with H2 in-memory database in Java. The following exception thrown.
SQL:
SELECT ACCT_RULE_ID, ACCT_ACTION_ID
FROM ACCT_RULE
WHERE (ACCT_ACTION_ID = ?)
AND (START_DATETIME <= to_char(?, 'mm/dd/yyyy HH:MI:SS AM'))
AND (STOP_DATETIME > to_char(?, 'mm/dd/yyyy HH:MI:SS AM'))
Replacing first parameter with Id and second and third parameter with new Date() value.
Exception:
Caused by: org.h2.jdbc.JdbcSQLException: Function "TO_DATE" not found; SQL statement:

you should be able to create your own to_date function
drop ALIAS if exists TO_DATE;
CREATE ALIAS TO_DATE as '
import java.text.*;
#CODE
java.util.Date toDate(String s, String dateFormat) throws Exception {
return new SimpleDateFormat(dateFormat).parse(s);
}
'
Of course you could also just use parsedatetime() per David Small's answer

One way to remove the time portion from a date-time field in H2, is to format the field as a string and then parse it. This worked for me:
PARSEDATETIME(FORMATDATETIME(field_name, 'yyyy-MM-dd'), 'yyyy-MM-dd')
H2's parse and format date functions follow the java.text.SimpleDataFormat semantics.
Yes, it is NOT super optimized. This is fine for our needs since we only use H2 for unit tests.

H2 database does not have TO_CHAR() function. But H2 database does have sysdate, dual, varchar2 which makes writing oracle query that will run on H2 database quite easy. So you can write a function instead which will H2 database function alias for making it handle date/timestamp with format. TO_CHAR(sysdate, 'DD/MM/YYYY HH24:MI:SS') can be used in H2 database.

Despite the lack of documentation there are TO_DATE function in PostgreSQL compatibility mode since 2.0.204.
Changelog ticket

Related

insert date in oracle database via jsp java

I've searched stackoverflow but did not found the solution (at least the way I want it).
I have a JSP page which calls a Java method to insert a date into Oracle database.
It passes a String.
The problem, how to build the string to execute the insert?
String myInsert = "INSERT INTO table_name
values (..., to_date(<<Java variable name>>, 'yyyy/mm/dd hh:mm'), ....);
where Java variable name refers to a variable of type String.
I want to let Oracle to the job, not necessarily using SimpleDateFormat, if it's possible. So, should I use '' or " "
Youre help would be very much appreciated
You should use a PreparedStatement along with its setDate function and not deal with date to string conversions yourself.
See http://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html#setDate(int,%20java.sql.Date)
String myInsert="INSERT INTO table_name values(...?)";
PreparedStatement ps=connection.prepareStatement(myInsert);
ps.setDate(1,<<java variable name>>);
...

PreparedStatement.setString on int/numeric columns in PostgreSQL JDBC

I am working with some legacy code that performs database operations in a generic way, so that the User/developer can work with a different database by changing only the JDBC driver.
I have a problem with PostgreSQL JDBC driver. My test case:
//ddl
CREATE TABLE test
(
id numeric,
name text,
)
//java code
String sqlCmd = "INSERT INTO test values (?, ?)";
PreparedStatement ps = connection.prepareStatement( sqlCmd );
ps.setString( 1, "1" );
ps.setString( 1, "name1" );
ps.executeUpdate();
With Postgres, the result of this case is an exception with message: "can't cast string to int..."
Is it inappropriate to use PreparedStatement.setString() to set values that database expects to be numeric?
Should I expect the JDBC driver to automatically convert java types to database types?
This test passes with other databases, including H2 and MySQL. Does the failure with PostgreSQL reflect a bug in the JDBC driver? Is it possible to make this case work without changing code?
The documentation for java.sql.PreparedStatement has this to say:
Note: The setter methods (setShort, setString, and so on) for setting IN parameter values must specify types that are compatible with the defined SQL type of the input parameter. For instance, if the IN parameter has SQL type INTEGER, then the method setInt should be used.
Whether a particular database or JDBC driver allows you to be sloppy about that is its own affair, but you are not justified in expecting that all drivers will allow such slop, even if certain ones do.
while migrating from oracle database to postgresql, I found that may help you to use setString with numeric types and date types as well.
Just you have to use the connection parameter stringtype=specified as mentioned in the documentation.
https://jdbc.postgresql.org/documentation/head/connect.html
You are using setString() method to insert integers and postgres could not do that, Use
ps.setInt(1, INTEGER_VALUE);

error using DATE function with HSQL

I have a project that uses SQL to access a DB2 database. I use the a HSQL database when running junit test cases on the code. The java project uses SQL via iBATIS.
I experience an error if HSQL encounters the DATE function, for example DATE(STATUS_CREATE_TS) any ideas on a solution?
--- Cause: java.sql.SQLException: user lacks privilege or object not found: DATE at
org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:98)
at
org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at
org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at
org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at
org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:203)
at
org.springframework.orm.ibatis.SqlMapClientTemplate.queryForObject(SqlMapClientTemplate.java:268)
Thank you.
This function is specific to DB2 and not supported directly by HSQLDB.
You can define the function for your tests as:
create function date(ts timestamp) returns date return cast(ts as date);
Have you tried the HSQL setting:
SET DATABASE SQL SYNTAX DB2 TRUE
As documented in http://hsqldb.org/doc/2.0/guide/dbproperties-chapt.html (Table 12.27).

NamedParameterJDBCTemplate and function syntax on different RDBMSs

I need to support both, Oracle und SQL Server. I have pretty identical procedures named get_current_date in both DBs. Now I have a query:
SELECT col1, col2 FROM table WHERE colDate < get_current_date()
This works beautifully in Oracle but lacks the dbo. prefix when executed in SQL Server.
Should Spring be able to handle that? What other options do I have? I dont think it should be necessary to determine the DB type myself.
Thank you!
Every JDBC driver should support the JDBC function escapes (defined in section 13.4.1 and listed in appendix D of the JDBC 4.1 spec). For the CURRENT_DATE it is CURRENT_DATE or CURRENT_DATE().
You can call this in a query as
SELECT col1, col2 FROM table WHERE colDate < {fn CURRENT_DATE}
You can query the list of supported functions of your specific driver with DatabaseMetaData.getTimeDateFunctions()
BTW: This assumes you just want the current date of the database. It is not a general solution for calling user defined functions in your query.
Should Spring be able to handle that?
--> get_current_date() is database method/procedure (may it be of database or your custom) so it is dependent on database, Spring would not take care of that.
What other options do I have?
--> Well you can put current date in query in code so it will be independent of database what you use. Something like :
String sql = "SELECT col1, col2 FROM table WHERE colDate < " + new Date();
How about get current date in java something like:
Calendar cal = Calendar.getInstance();
currentDate = cal.getTime();
and then you do:
SELECT col1, col2 FROM table WHERE colDate < currentDate

Why is my datetime parameter for a stored procedure being rejected?

I’m working on a Java server app which uses Spring 3 and C3P0 to access a Microsoft SQL Server 2008 R2 database, using version 3.0 of Microsoft’s JDBC 4 driver.
I have a sproc which has an input defined like so:
#modifiedAfter datetime = NULL
I’m using Spring to construct a call to this sproc.
I’m constructing a MapSqlParameterSource to contain my parameters:
MapSqlParameterSource in = new MapSqlParameterSource()
in.addValue("modifiedAfter", "2011-01-01T00:00:00", Types.TIMESTAMP)
But when I execute the call:
this.sprocCall.execute(in);
I get this:
com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting date and/or time from character string
…and I have no idea why.
I’ve tried a few variations on adding the parameter, such as passing it in as a Date, or specifying it as a VARCHAR, or not specifying the type — none of them work.
I’m beginning to suspect that the problem might be related to Spring. I wrote a little Groovy script to try to isolate the problem, and this works just fine:
dt = new DateTime("2012-02-01T00:00:00") // Joda DateTime
println sql.rows("exec spMySproc #modifiedAfter=${Sql.TIMESTAMP(dt.toString())}")
…but when I try the equivalent approach with MapSqlParameterSource, I get the above error.
At this point, I’m stumped.
Here’s the top of the stacktrace:
org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback; bad SQL grammar [{call spGetPoliciesCatalogPaged(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)}]; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting date and/or time from character string.
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:97)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:952)
at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:985)
at org.springframework.jdbc.core.simple.AbstractJdbcCall.executeCallInternal(AbstractJdbcCall.java:368)
at org.springframework.jdbc.core.simple.AbstractJdbcCall.doExecute(AbstractJdbcCall.java:342)
at org.springframework.jdbc.core.simple.SimpleJdbcCall.execute(SimpleJdbcCall.java:164)
… which is followed by some of my classes, then this:
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting date and/or time from character string.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:197)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet$FetchBuffer.nextRow(SQLServerResultSet.java:4762)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.fetchBufferNext(SQLServerResultSet.java:1682)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.next(SQLServerResultSet.java:955)
at com.mchange.v2.c3p0.impl.NewProxyResultSet.next(NewProxyResultSet.java:2859)
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:91)
at org.springframework.jdbc.core.JdbcTemplate.processResultSet(JdbcTemplate.java:1124)
at org.springframework.jdbc.core.JdbcTemplate.extractReturnedResults(JdbcTemplate.java:1023)
at org.springframework.jdbc.core.JdbcTemplate$5.doInCallableStatement(JdbcTemplate.java:995)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:936)
... 68 more
I tried updating to the latest version of spring-jdbc, 3.1.1, but it did not help.
I’d appreciate any help at all!
Thanks,
Avi
A co-worker of mine figured this out. It turns out that I had jumped the gun by blaming Spring and/or the Microsoft SQL Server driver. The problem was indeed an error when converting a character string to a date/time — but it wasn’t a problem directly with my parameter, it was a problem with a query that was being run by the dynamic SQL generated by my sproc, if I passed in this parameter.
The problematic code looks something like this:
IF #modifiedAfter IS NOT NULL BEGIN
SET #SQL = #SQL + N'AND mytable.ThingLastUpdated > #modifiedAfter'
END
Once the dynamic SQL contained in #SQL was actually executed, the contents of #modifiedAfter — a perfectly valid DATETIME, sent in from my Java code with no issues at all — were compared with the contents of mytable.ThingLastUpdated — which was a VARCHAR column which meant that SQL Server had to convert its contents to DATETIME so that they could be compared to #modifiedAfter — but not all values in mytable.ThingLastUpdated could be successfully converted, hence the conversion error being thrown.
The fix I decided on was to change the type of mytable.ThingLastUpdated to DATETIME, and do any needed conversion at insertion time, which I think will be more efficient than doing so at query time.
Lesson learned: if a SQL problem isn’t in my Java code, it’s probably in my SQL — not in Spring or a JDBC driver. PEBKAC.
How about passing the input as String/varchar and then converting it to datetime in the sproc?
This error is defenitely not a SQL problem bacause it converts that string "2011-01-01T00:00:00" to datetime successfully. The sql parameter type you have declared is of type TIMESTAMP and you are passing a string. I think that is where it fails to convert.
Try declaring the sql parameter type as string or varchar instead of TimeStamp.
Had a similar problem in and was looking # MSDN and looks like Sql-Server 2005 had a bug with precision conversion. Supposedly the version you are using has bumped up the precision 100ns. Will it be possible verify if the time-stamp precision. Here is the link for the discussion: Sql Server Conversion error

Categories

Resources