问题
I'm writing an integration test in Grails using GORM.
I want to do something like the following:
delete from Statistic
where stat_date = TO_DATE(:month_year, 'MON-YYYY')
But I get the following error:
java.sql.SQLException: Unexpected token: TO_DATE in statement [delete from statistics where stat_date=TO_DATE(?, 'MON-YYYY')]
I think the error is caused by the in memory database used by GORM (is it H2?) not supporting the to_date function.
Any ideas on how to write the delete SQL so that it works in a test and in live?
As I only really care about the Month and Year one thought I had would be to delete the records where the stat_date is between the first and last date of the given month.
Can any one think of a better way?
回答1:
Yes, H2 doesn't support TO_DATE, it's in 1.4.x roadmap. Instead you can use the EXTRACT function that exists both in Oracle DB and H2.
回答2:
This still comes up as number 1 on google searches so here's what worked for me.
My unit tests/local environment build and populate a schema using sql files. I created the following alias in the sql file
-- TO_DATE
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);
}
';
Notice the use of single quotes instead of $$ in h2 user defined functions as that is the only format that worked for me.
回答3:
I had to adjust bluesman's answer in order to make it work for the date formats that are commonly used in our Oracle sql.
This version supports dateFormats like 'DD-MON-YYYY'
-- TO_DATE
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 {
if (dateFormat.contains("MON")) {
dateFormat = dateFormat.replace("MON", "MMM");
}
if (dateFormat.contains("Y")) {
dateFormat = dateFormat.replaceAll("Y", "y");
}
if (dateFormat.contains("D")) {
dateFormat = dateFormat.replaceAll("D", "d");
}
return new SimpleDateFormat(dateFormat).parse(s);
}
';
I found the tips on this blog post http://javatechniques.com/blog/dateformat-and-simpledateformat-examples/ helpful in figuring out how to translate the Oracle date formats into SimpleDateFormat's formats.
回答4:
java.util.Date toDate(String dateTime, String dateFormat) throws Exception {
if (dateFormat.contains("MON")) {
dateFormat = dateFormat.replace("MON", "MMM");
}
if (dateFormat.contains("Y")) {
dateFormat = dateFormat.replaceAll("Y", "y");
}
if (dateFormat.contains("D")) {
dateFormat = dateFormat.replaceAll("D", "d");
}
if (dateFormat.contains("HH")) {
dateFormat = dateFormat.replaceAll("HH", "hh");
}
if (dateFormat.contains("hh24")) {
dateFormat = dateFormat.replaceAll("hh24", "hh");
}
if (dateFormat.contains("MI") || dateFormat.contains("mi")) {
dateFormat = dateFormat.replaceAll("MI", "mi").replaceAll("mi", "mm");
}
if (dateFormat.contains("SS")) {
dateFormat = dateFormat.replaceAll("SS", "ss");
}
return new SimpleDateFormat(dateFormat).parse(dateTime);
}
回答5:
Or you can define your own TO_DATE like
CREATE ALIAS TO_DATE AS $$
java.util.Date to_date(String value, String format) throws java.text.ParseException {
java.text.DateFormat dateFormat = new java.text.SimpleDateFormat(format);
return dateFormat.parse(value);
}
$$;
see http://www.h2database.com/html/features.html#user_defined_functions
来源:https://stackoverflow.com/questions/6829703/testing-the-oracle-to-date-function