I am porting my Java application which was developed for Windows to AIX Unix. On Windows it uses SQL Server for configuration. On AIX we are trying to use H2 database. Most of the code works but I am getting following error when executing query which has a datetime criteria.
org.h2.jdbc.JdbcSQLDataException: Cannot parse "DATE" constant "26-Jun-2019"; SQL statement:
SELECT EM_SCHEDULER_DAILY_POLL.* FROM EM_SCHEDULER_DAILY_POLL, EM_CONTROLLER WHERE EM_SCHEDULER_DAILY_POLL.CONTROLLER_ID =
EM_CONTROLLER.CONTROLLER_ID AND EM_SCHEDULER_DAILY_POLL.DATE_TIME
BETWEEN '26-Jun-2019' AND '26-Jun-2019 23:59:59' AND
POLLED_SUCCESSFULLY=0 AND EM_SCHEDULER_DAILY_POLL.CONTROLLER_ID=30
[22007-199]
This SQL works perfectly on SQL server but gives above exception on H2DB. How to solve this issue? I need both date and time in query.
Try using ISO date literals:
WHERE
EM_SCHEDULER_DAILY_POLL.DATE_TIME >= '2019-06-26' AND
EM_SCHEDULER_DAILY_POLL.DATE_TIME < '2019-06-27'
Note that since you are just looking for records on a single date, you could also try casting the column to date and doing a single comparison:
WHERE CAST(EM_SCHEDULER_DAILY_POLL.DATE_TIME AS DATE) = '2019-06-26'
As another comment, the first version I gave, with the two inequalities is sargable, meaning that the database should be able to use an index on the DATE_TIME column, while the second version, using the cast to date, probably cannot use an index. Therefore, the first version is the preferred way to go, if you ever need to tune or optimize your database.
You are passing a value with a time but H2 Date only don't have one.
Just remove the time in your second constant.
'26-Jun-2019 23:59:59' --> '26-Jun-2019'
DATE The date data type. The format is yyyy-MM-dd.
Mapped to java.sql.Date, with the time set to 00:00:00 (or to the next
possible time if midnight doesn't exist for the given date and
timezone due to a daylight saving change). java.time.LocalDate is also
supported on Java 8 and later versions.
Example:
DATE
Source :Data type of H2.
And since you just want one day (at least in that example), you can simply use :
DATE_TIME = '26-Jun-2019'
Note that Tim Biegeleisen's answer about ISO should be checked too, this format is not the best
Use TO_DATE function
Example - TO_DATE('01-12-2019','dd-MM-yyyy')
Insert into student(Id,Name,DOB) values(1, 'Abc', TO_DATE('01-12-2019','dd-MM-yyyy'))
There is a converter PARSEDATETIME() fuction.
For example if the date is 12/03/2013 we need to convert as PARSEDATETIME('12/03/2013','dd/MM/yyyy') check this SO.
The SQL statement look like Insert into invoice(id, invoice_date) values(1, PARSEDATETIME('12/03/2013','dd/MM/yyyy'))
Related
In my Java app I must save data to Oracle 11g with object created date and time and for this I convert java.util.Date() to java.sql.Date() in format as new java.sql.Date(new java.util.Date().getTime()). But I noticed, that after the data inserted, oracle truncate the time part of date and I get something like 16/09/2015. but I need format like this: 16/09/2015 9:55:44. the second format created by oracle's sysdate() procedure. How I can get the second format from java code?
From memory (it's been a while), java.sql.Date is used to hold dates (no time) only, if you want time information as well, you need to use java.sql.TimeStamp instead.
Do not use java.sql.Date if you want to store date and time. Just use java.util.Date without any conversion. Simple and easy. There is no need for java.sql.TimeStamp either.
And make sure your NLS settings (e.g. in SQL Developer) are such that they display both date and time as Oracle does not distinguish between dates with and without time.
I guess Oracle does not truncate. For example, if you use Oracle SQL Developer, you have to update NLS parameter "Date Format" to see a time.
By default it just equal "DD-MON-RR"
I am using mysql server 5.X
update ACA_CHECK_HISTORY set Datecolumn=CONVERT(VARCHAR(15),getdate(),103);
I am getting syntax error.
Try using MySQL syntax and not SQL Server syntax:
update ACA_CHECK_HISTORY
set CREATED_DATE = date_format(now(), '%Y-%m-%d');
Oh, wait, that's not quite what you want. It is better than what you want.
First, you should store date/time values in the native format in the database. If, for some reason, you cannot do this, then use an ISO standard format -- such as YYYY-MM-DD. This works for sorting and comparisons, which makes it very useful.
You can convert the value to an output format when presenting it to users. You seem to want the format '%d/%m/%Y'. Nothing wrong with that format. It is just a presentation format and should not be stored in the data.
If that column is a DATE or DATETIME or TIMESTAMP datatype, then simply do
update ACA_CHECK_HISTORY
set CREATED_DATE = NOW();
Better yet, you can avoid the UPDATE entirely if you use a TIMESTAMP with suitable DEFAULT.
When I try to use a java.sql.Timestamp value to insert into a DATETIME column in MySQL 5.6, I always get this error:
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect datetime value: '' for column 'invoice_date' at row 1
The original developer of this project had custom JARs that created the Prepared statements, such that java.util.Date is converted into Timestamp to be inserted into DATETIME and vice versa, as well as handled database connections. Note that this is my assumption since there is no documentation about it. Trying to use a timestamp to insert into DATETIME myself via PreparedStatement had the same results, using something like:
ps.setTimestamp(3, new Timestamp(date.getTime()));
I had to create my own connection so that I can use java.sql.Date to solve this problem. However it zeroes the time value as a result. I used
ps.setDate(3, new java.sql.Date(date.getTime()));
And I get something like
2013-06-27 00:00:00
in the table, since as we know java.sql.Date doesn't store the time.
Surprisingly, on a server that uses MySQL 5.0, this works normally. I'm assuming the millisecond value in Timestamp is causing the problem casting into DATETIME? Since the original works in older versions. Is there any way to resolve this without having to reinstall everything with 5.0?
If the problem is milliseconds, explicitly date format your timestamp. If the use case succeeds on MySQL 5.0 and you have different jdbc drivers deployed on 5.0 and 5.6, it is worth testing that driver over MySQL 5.6. Finally, you are not passing an index in your setters and the incorrect datetime value is the empty string. Have you verified in a debugger/logs that you are not attempting to insert an empty string?
I have a wierd hibernate related issue while setting a date field in an entity.
The date is interpreted as UTC in the java program (i did a System.out to make sure the date assigned is in 'UTC'. However, when hibernate actually persists to the database, the date is converted to local time and stored)
ex. the value has been set in the entity setter as "2009-09-09 00:08:08" - GMT
the actual value persisted to the database is "2009-09-08 08:08:08" - eastern time US.
I am unable to find out where and why this is happening and how to prevent it. Thanks
P.S. I am using joda date library and annotate the field with
#org.hibernate.annotations.Type(type = "org.joda.time.contrib.hibernate.PersistentDateTime")
However, when hibernate actually persists to the database, the date is converted to local time and stored) ex. the value has been set in the entity setter as "2009-09-09 00:08:08" - GMT the actual value persisted to the database is "2009-09-08 08:08:08" - eastern time US.
Ok, first, whatever column type are you using to store your date in MySQL (TIMESTAMP or DATETIME), neither stores the time zone. From Re: Storing timezone with datetime:
TIMESTAMP is seconds since 1970, sitting in 4 bytes. It is stored in GMT. That is, the TZ offset is applied as you store a value, then reapplied when you fetch it. (...)
DATETIME is an 8-byte string of digits "yyyymmddhhmmss". (...)
And second, unless a buggy behavior, my understanding is that the conversion is supposed be done either by the server or by the JDBC driver depending on the the server time zone settings so that you don't get inconsistent data.
In both cases, my point is that storing "2009-09-09 00:08:08" - GMT or "2009-09-08 08:08:08" - eastern time US from Java should yield to the same value in the database.
However, it looks like a different conversion is done when displaying them. This begs the question: how did you actually check the value of the "persisted date". Does the "problem" occur in your SQL client? In Java code?
References
9.6. MySQL Server Time Zone Support
21.3.4.1. Driver/Datasource Class Names, URL Syntax and Configuration Properties for Connector/J
Bug #15604: TimeZone discarded storing java.util.Calendar into DATETIME
MySQL documentation for DateTime says "MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format". That means mysql converts the 'milliseconds since epoch' to the above format. So now my question becomes, is timezone info also stored in mysql?
I've updated my initial answer (which was not totally accurate/exhaustive). Whether you're using DATETIME or TIMESTAMP, the answer is no.
Another observation I made is, the above date 'conversion' issue exists only when Im setting the date in the Java application. If I create a mysql trigger to update/set date using 'UTC_TIMESTAMP()', the date is displayed in the 'UTC' time.
The UTC_TIMESTAMP() function always returns the current UTC date and time.
What I'd like to know is:
How did you "reveal" the problem? With a SQL client or from Java?
What is the local time zone of the JVM?
What is the MySQL Server time zone?
What is the version of the MySQL JDBC Driver?
Could you do a test with raw JDBC?
In order to treat dates as UTC in the DB (for read/write), you can use this small open source library DbAssist. It uses a custom UtcDateType in order to map java.util.Date fields in your entities, so that they are treated by Hibernate as UTC in the DB. Since you are using JPA annotations, you would use the following dependency:
<dependency>
<groupId>com.montrosesoftware</groupId>
<artifactId>DbAssist-5.2.2</artifactId>
<version>1.0-RELEASE</version>
</dependency>
Applying the fix is easy, for example, when using Spring Boot, you have to make sure that you have #EnableAutoConfiguration annotation before the application class. If you are using another Hibernate version, just refer to github wiki to find the proper version of the fix and the installation guide. You can also read more about the time zone shift issue in this article.
This behaviour of Joda Time Contrib is fixed in my project Usertype for Joda Time and JSR310. See http://usertype.sourceforge.net/ which is practically otherwise a drop in replacement for JodaTime Hibernate.
I have written about this issue: http://blog.jadira.co.uk/blog/2010/5/1/javasqldate-types-and-the-offsetting-problem.html
Hope this helps,
Chris
I am inserting a record to orcle db through java application. The date value inserted as 02/10/0010 instead of 02/10/2010 HH:MM:SS AM/PM? I am using oracle jdbc connection. Does it problem with JDBC driver ?
Any input on this.
If you're using Oracle and JDBC, don't store Date in your table as a String. Make it a real Date and you'll spare yourself all this pain.
Check your date source. Is it two digit year or four?
Also, there are Oracle date mask formats which might cause that. Check the default for the installation.
Agree.
If you use a Java Date format (dunno its class just now) then JDBC driver performs all what is needed to store it in a Date column.
If you use String in java and/or varchar2 in Oracle table, you are doing it wrong. This will lead to implicit conversions, NLS settings and all that pain... if you are in this bad shape then you need explicit conversions and format masks on each date usage.
Use proper types.
I'm guessing that the value you're passing in is "02/10/10".
Date functions are pretty inconsistent about what they do with 2 digit years. If you are trying to enter dates for your "timeline of ancient history", having the computer assume that 2-digit dates must be shorthand for the 21st century would be very annoying. We really are better off with a WYSIWYG date interpretation.