Conversion failed when converting date and/or time from character string - java

i want to insert the record in sql server . Table name and columns are specified in this code,
String str_date=date;
DateFormat formatter ;
formatter = new SimpleDateFormat("MM/dd/yyyy");
date1 = (Date)formatter.parse(str_date);
System.out.println("Today is " +date1 );
try{
String query="INSERT INTO BULT_DATA " +
"(ULDT_ID" +
",ULDT_DESC" +
",ULDT_DT" +
",ULDT_ULTH_ID" +
",ULDT_DATA_FILE" +
",ULDT_MAX_ROW_NO" +
",ULDT_REC_STS" +
",ULDT_CRE_USER_ID" +
",ULDT_CRE_DT" +
",ULDT_UPD_USER_ID" +
",ULDT_UPD_DT" +
",ULDT_APRV_USER_ID" +
",ULDT_APRV_DT)" +
"VALUES ('"+
uploadID+"','"+
uploadDes+"','"+
date1+"','" +
templateID+"','"+
dataFile+"','"+
noRows+"','" +
"N','" +
"admin','" +
"2011-12-05 18:41:50.000','" +
"admin','" +
"2011-12-05 18:41:50.000','" +
"NULL','" +
"NULL')";
System.out.println("query :: "+query);
int stmnt= stmt.executeUpdate(query);
}catch (Exception e) {
e.printStackTrace();
}
but i got this exception
com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting date and/or time from character string.

First, only American humans use MM-DD-YYYY format for dates - everyone/everything else, especially databases, uses the ISO format YYYY-MM-DD.
JDBC when used correctly will handle formatting your object into your SQL for you.
Thirdly (and this is minor), prefer stmt.execute() over stmt.executeUpdate() for inserts - an insert is not an update, it's an insert. Although, it will work using either.
Putting it all together, you get something like this (for example):
String sql = "insert into table (int_col, date_col, boolean_col, text_col)" +
" values (?, ?, ?, ?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setObject(1, 7);
statement.setObject(2, new Date());
statement.setObject(3, true);
statement.setObject(4, "hello");
statement.execute();
Note:
the use of placeholders ? in the sql
the use of statement.setObject(n, object)
the absence of quotes around date and text placeholders
The JDBC driver will do all the necessary conversions and formatting for you for all "usual" java objects, especially enclosing values in quotes for you if quotes are required for that column/data type.
You can change your code around yourself to work in the way I've demonstrated here.

Use an ISO or ODBC date format for all values.
Or the legacy SQL Server yyymmdd hh:nn:ss
MM/dd/yyyy is not safe, neither are the the constants you gave for UPD_DT and ULDT_CRE_DT
'19980223 14:23:05'
{ts '1998-02-23 14:23:05'}
{d '1998-02-23'}
'1998-02-23T14:23:05'
And have you heard of SQL Injection, often caused by building SQL commands with string concatenation

your date1 object will be formatted using the standard toString() representation of java.lang.Date, which is unlikely to be compatible with the various date formats supported by your JDBC drivers.
Rather use another SimpleDateFormat object to format date1 into your SQL Server default date format before appending it to your query.
Also, do yourself a favour and read up on PreparedStatements and paramaterised queries; they really make this sort of stuff easier.

Related

java.sql.Timestamp to Date Conversion in Oracle SQL

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);

Why I obtain this error on a date field when I try to perform this query on SQL Server?

I am finding some difficulties trying to perform this SQL query (on Microsoft SQL Server) into a Java appliction.
So I have this method that perform a simple select query:
public void insertOrUpdate_TIRConsolidatoPolizza(QS_TirPolizza qsTir) throws Exception {
try{
log.debug("PucManager.insertOrUpdate_TIRConsolidatoPolizza");
// Reperisce i parametri della query dal parametro passato:
String numeroPolizza = qsTir.getPolizzaid().toString();
Long annoRiferimento = qsTir.getAnnoRiferimento();
String dataRiferimentoNav = qsTir.getDataRiferimentoNav() != null ? "'"+qsTir.getDataRiferimentoNav()+"'" : null;
String timestamp = qsTir.getTimestamp() != null ? "'"+qsTir.getTimestamp()+"'" : null;
String sql = "select * from TirConsolidatoPolizza" +
" where Polizzaid = " + numeroPolizza +
" and DataRiferimentoNav = " + dataRiferimentoNav;
log.debug("Query: " + sql);
PreparedStatement ps = con.prepareStatement( sql );
log.debug("Eseguo Query");
ResultSet rs = ps.executeQuery();
...................................................
...................................................
DO SOMETHING ELSE
...................................................
...................................................
}
The String sql variable value is (I see it printing it by log.debug()):
select * from TirConsolidatoPolizza where Polizzaid = 9999999999 and DataRiferimentoNav = 'Thu Jun 23 10:36:43 CEST 2016'
This query can't work because it seems that I have a problem with the DataRiferimentoNav value.
I obtain the following error message:
10:42:41 [SELECT - 0 row(s), 0.000 secs] [Error Code: 241, SQL State: S0001] Conversion failed when converting date and/or time from character string.
The DataRiferimentoNav (it is a datetime on the db table) value is taken from the qsTir.getDataRiferimentoNav() object field that is a String (I can't change it) representing a date and that was setted in this way elsewhere in my code:
qsTir.setDataRiferimentoNav(new Date().toString());
So, what is wrong? What am I missing? How can I solve this issue and correctly perform my query?
You need to proper format the date to be understood by the database:
Format formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String formatted = formatter.format(qsTir.getDataRiferimentoNav());
Ideally, you should avoid concatenating SQL as this can lead you to SQL injection vulnerabilities. Try to use parameterized queries to achieve your goal.

How do i correctly enter a Decimal Type through JDBC?

I've connected a java project (using netbeans) to a MySQL database, but I'm having trouble inserting data.
If i use this code it inserts just fine:
String update = "insert into expenses(Expense,Cost,Purchase_Date,Description)\n" +
"values('milk', 3.18, '2015-01-23','Grocery');";
but when i try and replace the insert values with these predefined values:
String ExpenseName;
Double ExpenseCost;
String ExpenseDate;
String ExpenseType;
and then use this code to insert the values:
String update = "insert into expenses(Expense,Cost,Purchase_Date,Description)\n" +
"values('"+ExpenseName+"',"+ExpenseCost+",'"+ExpenseDate+"','"+ExpenseType+"');";
I get the error: SQLException: Column 'Cost' cannot be null
my cost field in my database is defined as decimal(15,2)
Even more annoyingly, when i try and use this code to update as a test:
String update = "insert into expenses(Expense,Cost,Purchase_Date,Description)\n" +
"values('"+ExpenseName+"',3.18,'"+ExpenseDate+"','"+ExpenseType+"');";
i get another error saying:
SQLException: Data truncation: Incorrect date value: 'null' for column 'Purchase_Date' at row 1
this is confuses me a lot because through the database i have no issues with updating the Purchase_Date field in the expenses table with a '2015-01-23'. if its of any use that field is of type date. perhaps it's because the date object in my java is string?
You really should use a PreparedStatement
PreparedStatement pst= con.prepareStatement(
"insert into expenses(Expense,Cost,Purchase_Date,Description)" +
" values(?, ?, ?,?)");
pst.setString(1, ExpenseName);
pst.setDouble(2, ExpenseCost);
pst.setDate(3, new java.sql.Date(ExpenseDate.getTime()));
pst.setString(4, ExpenseType);
pst.executeUpdate();
Also, you should inititalize your variables properly.
Assuming that they are declared as fields, you should initialize them as :
String ExpenseName="SomeName";
Double ExpenseCost=1.8;
Date ExpenseDate=new Date();
String ExpenseType="Some Type";
Uninitialized variables could be the source of the SQLException, because ExpenseName and ExpenseDate would be concatenated as "null" in your SQL string.
You should always use a PreparedStatement to insert/ update data and not use String concatenation. This will not only help you with formatting the data correctly but also protect you against SQL injection attacks.

"Literal does not match the format string" error

When I try to execute the below code it gives me an java.sql.SQLException: ORA-01861: literal does not match format string error.
I am trying to copy some of the column values from customer1_details table to customer2_details table. The columns datatype which I am trying to move is TIMESTAMP(6) for TIME_REGISTERED, DATE_DISCHARGED columns and the datatype for DATE_OF_BIRTH column is DATE
try
{
Connection conn=Address.getOracleConnection();
int id = 1;
Date dob = null;
Timestamp timereg = null,datedischarged = null;
Statement stmt=conn.createStatement();
ResultSet res=stmt.executeQuery("SELECT TIME_REGISTERED,DATE_DISCHARGED,DATE_OF_BIRTH from customer1_details WHERE customer_id = '"+id+"' ");
if(res.next())
{
timereg=res.getTimestamp("TIME_REGISTERED");
datedischarged=res.getTimestamp("DATE_DISCHARGED");
dob=res.getDate("DATE_OF_BIRTH");
}
String sql1="INSERT INTO customer2_details(TIME_REGISTERED_3,DATE_DISCHARGED_3,DATE_OF_BIRTH,customer_ID) "
+ "VALUES('"+timereg+"','"+datedischarged+"','"+dob+"','"+id+"') ";
PreparedStatement pst=conn.prepareStatement(sql1);
pst.executeUpdate();
pst.close();
conn.close();
}
catch(Exception e)
{ System.out.print(e); }
It will be more helpful if anyone provides the answer without using INSERT INTO ... SELECT ... statement.
YOu can do it in one statement with a query like:
"INSERT INTO customer2_details (TIME_REGISTERED_3,DATE_DISCHARGED_3,DATE_OF_BIRTH,customer_ID)
SELECT TIME_REGISTERED,DATE_DISCHARGED,DATE_OF_BIRTH, customer_id
from customer1_details WHERE customer_id = '"+id+"' "
This is most likely caused by passing your Date and Timestamp variables as Strings to the insert statement.
When you insert or update Date or Timestamp values, there is a default format in which you can pass those values as strings. What you pass is java's idea of how to convert Dates and Timestamps into strings. These two don't seem to match.
Your best bet is probably to use bind variables, then the framework should take care of that.
An Alternative would be to use Oracle's to_date() function, where you can specify the format string. You would then define a format string which considers java's way of representing dates as strings. However, I am not sure if the java representation depends on the locale. If so, you would have to write you own date_to_string() method, which always returns dates in the same format, or your program may work on some computers, but not on others with a different locale.
And finally you can do an insert-select which bypasses the java layer entirely.
Read the timestamps as strings with getString();
OR call toString() in your java Timestamp object instances.
String sql1="INSERT INTO customer2_details(TIME_REGISTERED_3,DATE_DISCHARGED_3,DATE_OF_BIRTH,customer_ID) "
+ "VALUES('"+timereg.toString()+"','"+datedischarged.toString()+"','"+dob.toString()+"','"+id+"') ";

sql variable query in java

I have 3 comboboxes in Java which are ;
'departurecities={city1,city2,city3}
destinationcities={city1,city2,city3}
date={1,2,3,4,5,6...}
I want to define a variable for the date because I don't know, what user will bus date, so I need a variable for SQL query.
I want to query like that:
sql=select busid from buses where dep='city1'and des='city2' and
datebus=(????variable????);
how can I define it ???
Please help me ..
Thanks in advance
PreparedStatement
In case you want to pass a variable to your SQL statement, I would recommend a PreparedStatement. See Oracle Tutorial.
You can use setInt in order to pass an integer, setString to pass a String etc.
Here is the API.
Here is an example:
String result = null;
String query = "select busid from buses where dep='city1'and des='city2' and datebus=?";
try {
PreparedStatement preps = con.prepareStatement(query);
preps.setInt(1, Integer.parseInt((String) date.getSelectedItem()));
preps.execute();
rs = preps.getResultSet();
if (rs.next()) {
result = rs.getString(...);
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
I assume that datebus is declared as an integer in your database table.
You can use a String type for a constant like '2012-12-31 12:00 am', or, Date or GregorianCalendar if you want to manipulate days/date differences in Java.
In SQL, you can convert string or character values into SQL's internal date format with the to_date() function:
SQL examples:
to_date('29-Oct-09', 'DD-Mon-YY')
to_date('10/29/09', 'MM/DD/YY')
to_date('120109', 'MMDDYY')
So, if you wanted to create a SQL command from Java:
String date = "12/31/2012";
String dep = "city1";
String des = "city2";
String SQL = "INSERT INTO buses VALUES(" + dep + "," + des + ",to_date(" + date + ",'MM/DD/YYYY'));";

Categories

Resources