"Literal does not match the format string" error - java

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+"') ";

Related

How can I use strftime function with question mark in Java

I am planning to add 'Date' objects into the SQLite database. However, I am getting an error about the insertion being null.
The error is this
org.sqlite.SQLiteException: [SQLITE_CONSTRAINT_NOTNULL] A NOT NULL constraint failed (NOT NULL constraint failed: dates.Tarih)
at org.sqlite.core.DB.newSQLException(DB.java:909)
at org.sqlite.core.DB.newSQLException(DB.java:921)
at org.sqlite.core.DB.execute(DB.java:825)
at org.sqlite.jdbc3.JDBC3PreparedStatement.execute(JDBC3PreparedStatement.java:53)
This is my code. I suspect from the question marks. Because when I remove them and place them with 'now'. It actually works. But, the following code throws the above error.
Insert method
public static void insert(Date date, Date date2) {
try{
System.out.println(" date:"+date.toString());
String query = "insert into dates(Tarih,Tarih2) values(strftime('%d-%m-%Y',?), strftime('%d-%m-%Y',?))";
pst=conn.prepareStatement(query);
pst.setObject(1,date);
pst.setObject(2,date2);
pst.execute();
}catch (SQLException e){
e.printStackTrace();
}
}
Probably you have defined the column Tarih as NOT NULL and your code is trying to insert a null value in the table.
The reason that you get null from strftime() is because you don't pass a valid date for SQLite.
For SQLite valid dates/datetimes are either strings in the format yyyy-MM-dd hh:mm:ss, or integer unix epoch times or floating point numbers representing julian days.
What you pass are Date objects and this is your mistake.
One way to solve the problem is to extract from each of the Date objects an integer representing unix epoch time and pass that to strftime():
public static void insert(Date date, Date date2) {
try{
long d = date.toInstant().toEpochMilli() / 1000;
long d2 = date2.toInstant().toEpochMilli() / 1000;
String query = "insert into dates(Tarih,Tarih2) values(strftime('%d-%m-%Y', ?, 'unixepoch'), strftime('%d-%m-%Y', ?, 'unixepoch'))";
pst=conn.prepareStatement(query);
pst.setLong(1, d);
pst.setLong(2, d2);
pst.execute();
} catch (SQLException e){
e.printStackTrace();
}
}

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.

String found, numeric expected in Oracle function called from Java

EDIT
Putting this here in case it helps others. My problem was a failure in understanding how PreparedStatement works. I had believed that the "?"...setInt() syntax was a simple substitution that constructs an SQL statement, interprets it and sends that to the DB, which is not the case. The answers below explain in detail the problem.
ORIGINAL QUESTION
I'm having some trouble getting an Oracle package function call to execute from within a Java app. I am receiving the below error:
ORA-01858: a non-numeric character was found where a numeric was expected
I believe I have constructed the call correctly, and the only place I'm using a string is for a date field (not a numeric one). The function has the signature:
function f_get_mr_target(a_plan_id number,a_machine number,a_shift_id number,a_shift_dt date) return number;
My java code invoking the function is as follows:
public Double checkMRTarget(int planId, int machineNum, int shiftId, String date)
{
//Instantiate the return value
Double mrTarget = null;
//Get the MR target
try
{
//Ready the connection
con = nativeDataSource.getConnection();
//The query string
String sql = "select pkg_bcs.f_get_mr_target(?,?,?,?) target from dual";
//Prepare the query
stmt = null;
stmt = con.prepareStatement(sql);
stmt.setInt(1, planId);
stmt.setInt(2, machineNum);
stmt.setInt(3, shiftId);
stmt.setString(4, date);
//Execute the query
ResultSet rs = stmt.executeQuery();
//Extract the value from the result set
mrTarget = rs.getDouble("target");
}
catch (Throwable e)
{
System.out.println("Error getting mrTarget: " + e);
}
finally
{ closeDBConnections(); }
//Return the value
return mrTarget;
}
Con is a public Connection object shared by all other methods in the class. Stmt is a PreparedStatement object, also shared. The parameters are passed as follows:
planId = 986548
machineNum = 5227
shiftId = 10
date = "trunc(sysdate)"
I've verified that running
select pkg_bcs.f_get_mr_target(986548, 5227, 10, trunc(sysdate)) target from dual;
works just fine in SQLDeveloper. As far as I can tell, it's getting a number where it expects a number
You've called setString, so Java sent a String that Oracle can't implicitly convert into a DATE.
You can convert it to a java.sql.Date, java.sql.Time, or java.sql.Timestamp by first parsing the date with a SimpleDateFormat, and creating the appropriate object, and calling setDate, setTime, or setTimestamp instead of setString.
Alternatively, you can get Oracle to convert it by calling to_date in your JDBC SQL:
// Your date format may vary.
String sql = "select pkg_bcs.f_get_mr_target(?,?,?,to_date(?, 'YYYY-MM-DD')) target from dual";
the 4th parameter which is date do not work with String. It waits for a Date object.
Here is your method signature, pass a Date object instead of String.
public Double checkMRTarget(int planId, int machineNum, int shiftId, Date date)
Substituting a string datatype to a Date parameter is a catastrophe. It will surely the ORA-01858 exception in this case (in context of you code).
Parameter substitution demands exact binding which serves its purpose of being strongly typed.
Please convert the fourth parameter i.e. the string parameter into a date object. & then implement what you wish to. It should work fine then.
Also, trunc(sysdate) in SQL query does not return a string to the SQL client. Rather it returns the date(internal conversion). This is designed such that the parser recognize the date type efficiently and consistently.

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

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

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.

Categories

Resources