I'm making a library project in Java that is supposed to record data about members, books, users and borrowings. When I create a new object of the class Borrowing the system automatically notes the IssueDate.
The problem happens when I try to make a record of the book being returned with and UPDATE SQL QUERY and record the ReturnDate.The query works but in DB in the corresponding field I always get 30/12/1899 as a ReturnDate.
The SQL query goes like this:
UPDATE Booking SET Returned = 1, ReturnDate = "+ sdf.format(getReturnDate()) +" WHERE BookingID =" + getBookingID()
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
setReturnDate(new Date());
I decided to format it to String and format dd/mm/yyyy because that is the format Access recognizes when I enter it manually and it worked with all other queries (like creating a new Booking and IssueDate) in the project and it enters the real date.
I have already tried using java.sql.Date instead, switching to the US format (mm/dd/yyyy) and using # (hash marks) at the beginning and the end of the date string and none of those worked.
Do you have any other ideas?
Consider using a PreparedStatement instead, see Using Prepared Statements for more details
Instead of setting the "text" of the query, use setDate of the PreparedStatement and let the JDBC driver work it out
Related
I have problem with HQL where I am setting the query parameters. One of them is Date. When I debug the code there is Date with time entering the method. I set the parameter using setParameter(timestamp, new Timestamp(date.getTime())) or query.setTimestamp...etc etc I used many combinations...
When I use p6spy to examine the SQL comming from app to the DB there is only '29-Jan-21' or other date without time.
I am using hibernate 5.1.0 final and postgre DB. I'll be glad for any help.
Example:
Query query = getSessionFactory().getCurrentSession().createQuery("SELECT user FROM UserEntity cr WHERE user.userStatus.id = :statusId AND :timestamp >= user.valid_to");
This is how I tried to set the timestamp parameter:
query.setParameter("timestamp", new Timestamp(date.getTime()));
query.setParameter("timestamp", date, TimestampType.INSTANCE);
query.setTimestamp("timestamp", date);
query.setTimestamp("timestamp", new Timestamp(date.getTime()));
Problem is that the generated SQL replace timestamp by '29-Jan-21' or other date I choose but without time. The date parameter comes to the method from UI and it contains full date with time.
I'm using Java 8 with Spring's JdbcTemplate and Oracle 12.1,
I want to update record and get the exact time record was updated
jdbcTemplate.update(UPDATE_SQL, null);
Currently it returns (int) the number of rows affected, but I want the exact updated date
Must I send a new request to get current time which may be inaccurate?
More exact will be to save in column updated date, but then to execute another SQL
Is there another option to get updated date in one query?
Obviously, I don't want to use get date from code also (as new Date()) also because server time is/can be different than DB Time
You decided to use JDBCTemplate most probably to simplify the code in comparison to plain JDBC.
This particular problem IMHO makes the plain JDBC solution as proposed in other answer much simpler, so I'd definitively recommend to get the database connection from JDBCTemplate and make the insert in a JDBC way.
The simplest solution using JDBCTemplate that comes to my mind is to wrap the insert in a PROCEDURE and return the timestamp as an OUT parameter.
Simple example (Adjust the time logik as required)
create procedure insert_with_return_time (p_str VARCHAR2, p_time OUT DATE) as
BEGIN
insert into identity_pk(pad) values(p_str);
p_time := sysdate;
END;
/
The call is done using SimpleJdbcCall
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate).withProcedureName("insert_with_return_time");
SqlParameterSource params = new MapSqlParameterSource().addValue("p_str", str);
Map<String, Object> out = jdbcCall.execute(params);
The Map contains the returned value e.g. [P_TIME:2019-10-19 11:58:10.0]
But I can only repeat, in this particular use case is IMHO JDBC a rescue from JDBCTemplate;)
You're right that passing new Date() would store the server time rather than the DB time.
To store the DB time you can set your timestamp to the DB system timestamp systimestamp then you could run a query to retrieve that row and its updated timestamp.
If you want to update the row and get the updated timestamp in a single execution then you could do the following using RETURNING INTO where TimestampUpdated is your column name:
Connection con = ...;
String sql = "UPDATE TableName SET <updates> , TimestampUpdated = systimestamp RETURNING TimestampUpdated INTO ?";
CallableStatement statement = con.prepareCall(sql);
statement.registerOutParameter(1, Types.TIMESTAMP);
int updateCount = statement.executeUpdate();
Timestamp timestampUpdated = statement.getInt(1);
System.out.println("Timestamp Updated = " + timestampUpdated);
Here is a related link doing this with JdbcTemplate
I'm using Java 8 with Spring's JdbcTemplate and Oracle 12.1,
I want to update record and get the exact time record was updated
jdbcTemplate.update(UPDATE_SQL, null);
Currently it returns (int) the number of rows affected, but I want the exact updated date
Must I send a new request to get current time which may be inaccurate?
More exact will be to save in column updated date, but then to execute another SQL
Is there another option to get updated date in one query?
Obviously, I don't want to use get date from code also (as new Date()) also because server time is/can be different than DB Time
You decided to use JDBCTemplate most probably to simplify the code in comparison to plain JDBC.
This particular problem IMHO makes the plain JDBC solution as proposed in other answer much simpler, so I'd definitively recommend to get the database connection from JDBCTemplate and make the insert in a JDBC way.
The simplest solution using JDBCTemplate that comes to my mind is to wrap the insert in a PROCEDURE and return the timestamp as an OUT parameter.
Simple example (Adjust the time logik as required)
create procedure insert_with_return_time (p_str VARCHAR2, p_time OUT DATE) as
BEGIN
insert into identity_pk(pad) values(p_str);
p_time := sysdate;
END;
/
The call is done using SimpleJdbcCall
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate).withProcedureName("insert_with_return_time");
SqlParameterSource params = new MapSqlParameterSource().addValue("p_str", str);
Map<String, Object> out = jdbcCall.execute(params);
The Map contains the returned value e.g. [P_TIME:2019-10-19 11:58:10.0]
But I can only repeat, in this particular use case is IMHO JDBC a rescue from JDBCTemplate;)
You're right that passing new Date() would store the server time rather than the DB time.
To store the DB time you can set your timestamp to the DB system timestamp systimestamp then you could run a query to retrieve that row and its updated timestamp.
If you want to update the row and get the updated timestamp in a single execution then you could do the following using RETURNING INTO where TimestampUpdated is your column name:
Connection con = ...;
String sql = "UPDATE TableName SET <updates> , TimestampUpdated = systimestamp RETURNING TimestampUpdated INTO ?";
CallableStatement statement = con.prepareCall(sql);
statement.registerOutParameter(1, Types.TIMESTAMP);
int updateCount = statement.executeUpdate();
Timestamp timestampUpdated = statement.getInt(1);
System.out.println("Timestamp Updated = " + timestampUpdated);
Here is a related link doing this with JdbcTemplate
A strange behaviour of select query just came up on my way while im doing a task for the uni.Im pulling data from a table i got on my oracle db.
selectString = "select * from reservation";
prestatement = dbConnection.prepareStatement(selectString);
rs = prestatement.executeQuery(selectString);
while (rs.next()) {
String rdate = rs.getString("reservdate").substring(0, 10);
jComboBox1.addItem(rdate);
//....
//....etc..
The thing is that what is displayed on my combo box is a think like '1999-10-10'
After that i have to pull some data where i must select the ones with the date of the selected item on the combo box.Well there's my problem.
String x = String.valueOf(jComboBox1.getSelectedItem());
selectString="select * from reservation where reservdate='"+x+"'";
//...etc..
After i run that im getting an sql exception with message : Message: ORA-01861: literal does not match format string
I searched a little bit the web and found that if i run this select query everything works fine
selectString="select * from reservation where reservdate='10-OCT-99'";
So my question is, what is the best way to make this work.I mean should i try edit all the dates from combo box to this format? or im doing something wrong all the way and should change that?
Thanks in advance.
You can either:
1- Override your related class' (whatever object that getSelectedItem returns, in this particular case its already a String and you may not need that String.valueOf() call) toString method to achieve the needed format of yours. (Kind of bad to do)
2- Let Oracle DB handle it with its TO_DATE function (Kind of a better practice to do)
"TO_DATE(yourDateString,dateFormat)"
String date = String.valueOf(jComboBox1.getSelectedItem());
selectString="select * from reservation where reservdate= TO_DATE('" + date + "','DD-MON-YY')";
And to prevent SQL injections, using the latter approach with a PreparedStatement would look like this:
String date = String.valueOf(jComboBox1.getSelectedItem());
String selectString="select * from reservation where reservdate= TO_DATE(?,'DD-MON-YY')";
PreparedStatement preStatement = dbConnection.prepareStatement(selectString);
preStatement.setString(1,date);
ResultSet rs = preStatement.executeQuery();
Official Docs
I have a table , there are 4 fields: name, start date and time (Timestamp) ,end date and time (timpestamp) , car.
In Java/MySQL,
I need to compare database start date time and end start date time and compare with value given in textbox date time field .
Now problem is that we need to book person(driver) and car, if car and person
are not booked in given time (that is checked by database) , then we can booked it else not.
Please tell me a logic/query to do this.
If you have code please mention it.
Try this query,
SELECT name FROM table having '2014-11-28' between start_date and end_date;
You can use this query to check availability.
SELECT name FROM table WHERE start_date < '2014-03-13 11:42:28' AND end_date > '2014-03-13 11:42:28' limit 1
If you get any name, then you can not book new driver. Also look at mysql date and time functions.