I'm trying to insert a timestamp into a database, but my code throws an exception, which tells me it's something with my sql statement.
The exception message shown is:
"Fout in Rit_ToevoegenController.okKnop(): SQLException in RitDB.voegRitToe() - statement"
okKnop is a different method that calls voegRitToe().
The type of the column called 'starttijd' is TIMESTAMP, and the DB Data type is DateTime.
i'm fairly certain that it's the timestamp that causes problems, because the other 2 are just a String and an int.
Any help with making it work would be greatly appreciated. I need to insert both the time and date into the database for comparing later.
public void voegRitToe(Rit r) throws DBException{
Timestamp starttijd = new Timestamp(System.currentTimeMillis());
//Date date = new Date(starttijd.getTime());
try(Connection conn = ConnectionManager.getConnection();){
try(PreparedStatement stmt = conn.prepareStatement("insert into rit(starttijd, lid_rijksregisternummer, fiets_registratienummer) values(?,?,?)");){
stmt.setTimestamp(1, starttijd);
stmt.setString(2, r.getLid().getRegisterNr());
stmt.setInt(3, r.getFiets().getRegisNr());
stmt.execute();
}
catch(SQLException sqlEx){
throw new DBException("SQLException in RitDB.voegRitToe() - statement");
}
}
catch(SQLException sqlEx){
throw new DBException("SQLException in RitDB.voegRitToe() - verbinding");
}
}
TIMESTAMP and DATETIME serve different purposes; TIMESTAMP is for automatic time stamping.
java.util.Date starttijd = new java.util.Date(System.currentTimeMillis());
java.util.Date starttijd = new java.util.Date(); // Or this
I guess you came at Timestamp, as java.sql.Date wraps java.util.Date by setting the time part to zero!
If the database server's time is correct, one could also do:
... VALUES(NOW(), ?, ?)
By the way, java 8 introduces new date/time classes and "improve" upon the JDBC usage, if you have a java 8 compliant driver.
Related
I have an column defined as datetime(2) and I have to create a new date in this format - 2016-01-01T19:33:15-05:00
Entity: private Date transactionTime;
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
Date date = null;
try {
date = formatter.parse(formatter.format(new Date()));
} catch (ParseException e) {
e.printStackTrace();
}
obj.transactionTime(date);
It is getting inserted in SQL as like this - "2021-08-26 14:19:09.0000000" but I need insert this in the format mentioned above.
There is only column type, datetimeoffset that can hold the timezone offset (e.g. -05:00 as mentioned in your question) value. Check the Data type mappings documentation to learn more about it.
So, if you want to store the timezone offset value, change the column type to datetimeoffset. After that, you will be able to insert the value which you have mentioned in the question.
You can use the following code to access the stored value:
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT foo FROM mytable WHERE ...");
while (rs.next()) {
DateTimeOffset dateTimeOffset = rs.getObject(1, DateTimeOffset.class));
System.out.println(dateTimeOffset);
}
rs.close();
st.close();
where foo the name of the column of type, datetimeoffset.
I am using mysql 5.7.x version. Also i am using java 8. I am trying to insert java.time.instant current datetime in millisecond precision into my mysql database from java code. For that I am using preparedstatement.
The table in my database is:
CREATE TABLE `test_table` (
`id` INT NOT NULL AUTO_INCREMENT,
`timestamp` TIMESTAMP(3) NOT NULL,
PRIMARY KEY (`id`));
My java code to insert is:
Instant instant = Instant.now().truncatedTo(ChronoUnit.MILLIS);
try (Connection conn = DbConnection.getCon();
PreparedStatement ps = conn.prepareStatement("INSERT INTO test_table (timestamp) VALUES (?)");) {
ps.setTimestamp(1, Timestamp.from(instant));
ps.executeUpdate();
LOG.info("Instant: {} and long: {}", instant, instant.toEpochMilli());
} catch (SQLException ex) {
LOG.error(ex.getMessage());
}
From my log, I can see instant with milliesecond as: 2019-07-30T10:52:34.865Z.
But in my mysql database it becomes: 2019-07-30 10:52:34.000Z
I have searched so many questions and answers in stack but none seems to work for me.
Update 1:
I tried using setObject as:
ps.setObject(1, Timestamp.from(instant));
But still same result. Cannot retrieve the milliseconds in database.
MySQL has FROM_UNIXTIME() function that can take long values inside and returns a representation of the unix_timestamp in 'YYYY-MM-DD hh:mm:ss' or 'YYYYMMDDhhmmss.uuuuuu' format.
Reference from their manual here:
FROM_UNIXTIME()
Since I have milliseconds since epoch, thus I have to use
FROM_UNIXTIME(instant.toEpochMilli() * 0.001)
in my insert statement.
Yes nothing needs to be changed in database. The only things that are changed are in java code which are setObject() function used for preparedStatement, passing instant.toEpochMilli() as the argument there and finally use of FROM_UNIXTIME() function inside insert statement.
My final java code looks something like this:
Instant instant = Instant.now().truncatedTo(ChronoUnit.MILLIS);
try (Connection conn = DbConnection.getCon();
PreparedStatement ps = conn.prepareStatement("INSERT INTO test_table (timestamp) VALUES (FROM_UNIXTIME(?*0.001))");) {
ps.setObject(1, instant.toEpochMilli());
ps.executeUpdate();
LOG.info("Instant: {} and long: {}", instant, instant.toEpochMilli());
} catch (SQLException ex) {
LOG.error(ex.getMessage());
}
I have run into this weird Timestamp to Date Conversion issue in Oracle SQL.
Here is the SQL statement:
String INSERT_SQL = String.format("INSERT INTO AUDIT_TASK (%s, %s, %s, %s) VALUES (AUDIT_TASK_SEQ.nextval,?,?,?)",ID,CLASS_NAME,TASK_STEP_TIMESTAMP,OPERATOR);
java.util.Calendar utcCalendarInstance = Calendar.getInstance(TimeZone .getTimeZone("UTC"));
java.util.Calendar cal = Calendar.getInstance();
final PreparedStatement stmt = con.prepareStatement(INSERT_SQL);
stmt.setString(1, audit.getClassName().getValue());
// Save the timestamp in UTC
stmt.setTimestamp(2,new Timestamp(cal.getTimeInMillis()), utcCalendarInstance);
When I execute this statement, while most of the times the creation_date and task_step_timestamp dates are same, but sometimes I get the task_step_timestamp generated with some bogus dates- like '25-APR-0000' or '00-Jan-0001' etc.
ID | Creation_date | Task_step_timestamp
1 |27-APR-2018 17:58:53| 25-APR-0000 09:00:45
2 |27-APR-2018 18:06:25| 00-Jan-0001 09:18:25
The data type of task_step_timestamp column in Oracle DB is 'DATE'.
Can some one suggest the cause of this inconsistent conversion of timestamp to date?
I don't understand why you are using String#format here. Just use a regular insert which mentions explicit columns:
String INSERT_SQL = "INSERT INTO AUDIT_TASK (ID, ERROR_MESSAGE, TASK_STEP_TIMESTAMP, OPERATOR) ";
INSERT_SQL += "VALUES (AUDIT_TASK_SEQ.nextval, ?, ?, ?)";
PreparedStatement stmt = con.prepareStatement(INSERT_SQL);
Then bind your values:
stmt.setString(1, audit.getErrorMessage() != null ? audit.getErrorMessage().getValue() : null);
stmt.setTimestamp(2, new Timestamp(cal.getTimeInMillis()), utcCalendarInstance);
stmt.setString(3, audit.getClassName().getValue());
Note carefully that the placeholders, in order from left to right, are for the error message, task step timestamp, and operator. Your original code appears to be binding the parameters out of order. By using an insert statement which explicitly mentions the columns, you may avoid this problem.
Edit:
It also doesn't make sense to me why you are worrying about time zones for your timestamp. Just get the numbers of milliseconds since the epoch, and then let the database store that as UTC:
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
stmt.setTimestamp(2, timestamp);
The intent of my overall program is to fetch values from Access database and display in jtable for a particular date.
I have a table in access database where for_date field is stored as a Date/Time field and format is Short date(dd-MM-yyyy). Now my program requires me to retrieve the rows from the database for a particular date.I used SimpleDateFormat to convert it in the format as access database but it gives error. The error I get is:- net.ucanaccess.jdbc.UcanaccessSQLException:UCAExc:::3.0.4 incompatible datatypes in combination.This exception may happen if you add integers representing units of time directly to datetime values using the arithmetic plus operator but without specifying the unit of date.In this specific case you have to use,for example, +1 DAY
My code is as follows:-
String table_sel = "ISGS_table";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String date1 = sdf.format(report_date.getDate());
try{
String sql = "Select reporting_date as REPORTING_DATE,for_date as FOR_DATE,outage_date as OUTAGE_DATE,outage_time as OUTAGE_TIME,stat_detail as STATION_DETAILS,res_date as RESTORATION_DATE,rest_time as RESTORATION_TIME,rest_reason as RESTORATION_REASON from " + table_sel+" where for_date='" + date1 + "'";
Connection con = null;
Statement st = null;
ResultSet rs = null;
PreparedStatement pst = null;
String dbURL = "jdbc:ucanaccess://C:\\Users\\Dell_PC\\Documents\\SYSTEM_OUTAGE_REPORT.accdb";
con = DriverManager.getConnection(dbURL);
st = con.createStatement();
pst = con.prepareStatement(sql);
rs = pst.executeQuery();
jTable1.setModel(DbUtils.resultSetToTableModel(rs));
con.close();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
You are receiving that error message because you are passing the value for for_date as a string literal. UCanAccess follows the Access SQL convention of using hash marks (#) as the delimiter for date/time literals.
So, this will fail with the error you cited
... WHERE for_date = '2017-02-03'
whereas this will work
... WHERE for_date = #2017-02-03#
Note that it would be considered better form if you were to use a PreparedStatement with
... WHERE for_date = ?
and pass the date value using PreparedStatement#setDate.
I have a JDateChooser in my form. and I need to insert it's Date value into DB.
I used this method just after "public class Nonacademic extends javax.swing.JInternalFrame {" ,
and the method I used is mentioned below,
public static java.sql.Date convertUtilDateToSqlDate(java.util.Date date){
if(date != null) {
java.sql.Date sqlDate = new java.sql.Date(date.getTime());
return sqlDate;
}
JOptionPane.showMessageDialog(null, "No Dates are Specified!");
return null;
}
and In my Add button's actionPerformed event I used
Connection c=DBconnect.connect();
Statement s = (Statement) c.createStatement();
PreparedStatement statement = c.prepareStatement("INSERT into nonacademic ( empId, name, Dob, JoinedDate) VALUES (?,?,?,?)");
statement.setString(1,txtEmpId.getText());
statement.setString(2, txtNmae.getText());
statement.setDate(3,convertUtilDateToSqlDate( (Date) jDateChooserDOB.getDate()));
statement.setDate(4, convertUtilDateToSqlDate( (Date) jDateChooserDateOfJoined.getDate()));
statement.executeUpdate();
Problem is It is gives this error,
java.lang.ClassCastException: java.util.Date cannot be cast to java.sql.Date
When I search for a solution to this, I found that this runtime error happens due to Parent class Instance is casting into child class.So can u give me a suggestion to correct this code.
Note:
After done coding above code when I select a Date in JDateChooser It appears as this 2015-08-06, Before code above stuff It appears as Aug 6,2015.
Try below statements,
statement.setDate(3,convertUtilDateToSqlDate(jDateChooserDOB.getDate()));
statement.setDate(4, convertUtilDateToSqlDate(jDateChooserDateOfJoined.getDate()));
Reason:
This is because of import statements. You might have imported only java.sql.Date or java.sql.* statement in your code. All "Date" class you mentioned in your program will be treated as java.sql.Date. So JVM is trying to converting java.util.Date to java.sql.Date in those statement and throwing exception.