Non-numeric character was found where a numeric was expected - java

I'm getting error as
ORA-01858: a non-numeric character was found where a numeric was expected
for a query in Eclipse but the same query is running fine in Toad.
I tried changing the date to to_char.
String query3 = "SELECT TXN_DATETIME FROM S3_ANTI_MONEY_LAUNDERING_TDS WHERE TRUNC(ROW_LOADED_DATE_TIME)='30-OCT-2018' AND SRC_FEED_NUM='63' AND BANK_ID IN('ISPP') AND SRC_RECORD_NUM IN('3','6')";
statement = connection.createStatement();
rs3 = statement.executeQuery(query3);
ArrayList<String> resultList1 = new ArrayList<String>();
while (rs3.next()) {
String result = rs3.getString(1) ;
resultList1.add(result);

The problem is likely the way that you have the date specified.
If you do not provide a proper date literal, then Oracle is using your NLS_DATE_FORMAT for the implicit conversion from text to date, and this might not be what you expect.
Replace this:
String query3 = "SELECT TXN_DATETIME FROM S3_ANTI_MONEY_LAUNDERING_TDS WHERE TRUNC(ROW_LOADED_DATE_TIME)='30-OCT-2018' AND SRC_FEED_NUM='63' AND BANK_ID IN('ISPP') AND SRC_RECORD_NUM IN('3','6')";
With this:
String query3 = "SELECT TXN_DATETIME FROM S3_ANTI_MONEY_LAUNDERING_TDS WHERE TRUNC(ROW_LOADED_DATE_TIME) = DATE '2018-10-30' AND SRC_FEED_NUM='63' AND BANK_ID IN('ISPP') AND SRC_RECORD_NUM IN('3','6')";
The proper way to do a DATE literal in Oracle is one of these:
DATE 'yyyy-mm-dd'
TIMESTAMP 'yyyy-mm-dd hh24:mi:ss'
Of course, you can use whatever mask you wish in this syntax:
TO_DATE('2018-10-30 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
Oracle docs for NLS_DATE_FORMAT
Oracle docs for DATE and DATETIME literals
Finally, if your code is building that query on the fly, it's much better to use bind variables and a prepared statement. Just make sure you are familiar with the nuances of Java dates and timestamps vs. Oracle dates and timestamps.

Without seeing your database schema, I'd say this looks fishy:
SRC_RECORD_NUM IN('3','6')
I personally would NEVER declare a character field with a _NUM suffix, but your IN clause is passing character data. I bet you need to do:
SRC_RECORD_NUM IN (3,6)
But I'm guessing based entirely on the name of the field.

Related

How to set java.sql.Timestamp in prepared statement when used for TIMESTAMPDIFF calculation?

I am currently facing the following issue:
I want to get the time difference in seconds between the current time and the given timestamp in a prepared statement.
public List<Foo> getFoos(String id, Timestamp ts) {
return jdbcTemplate.query(
"SELECT TIMESTAMPDIFF(2, (CURRENT TIMESTAMP - ?)) AS NEW_TIMESTAMP FROM SCHEMA.TABLE WHERE ID = ?",
new Object[]{ts, id},
(rs, rowNum) -> mapFooFromResultSet());
}
This query will fail with
com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-402, SQLSTATE=42819, SQLERRMC=-, DRIVER=
-402 AN ARITHMETIC FUNCTION OR OPERATOR function-operator IS APPLIED TO CHARACTER OR DATETIME DATA
I am using a DB2 database and cannot switch to any other db driver.
So my question would be how do I achieve the time difference in a sql statement between the current time and a given java.sql.Timestamp value?
Thank you in advance for your help.
It seems that the function TIMESTAMPDIFF does not accept a Timestamp, but expects a String value like specified in the string-expression paragraph of the docs. In the examples they make use of the CAST, CHAR and TIMESTAMP functions, so the following might solve the problem.
Instead of a Timestamp object, a corresponding String value needs to be specified in the format YYYY-MM-DD-hh.mm.ss:
SELECT TIMESTAMPDIFF(2, CHAR(CURRENT TIMESTAMP - TIMESTAMP(?))) AS NEW_TIMESTAMP
FROM SCHEMA.TABLE
WHERE ID = ?
As mentioned by #Idz the TIMESTAMPDIFF expects a string-expression. Look at the last example on the provided website you will see a solution.
For my example it works with the following code:
"SELECT TIMESTAMPDIFF(2, CAST(CURRENT_TIMESTAMP - CAST(? AS TIMESTAMP) AS CHAR(22))) AS NEW_TIMESTAMP FROM SCHEMA.TABLE WHERE ID = ?"

How to show date between start date and end date in ms access

i have error in my code
net.ucanaccess.jdbc.UcanaccessSQLException:
UCAExc:::3.0.7 unexpected token: 2016 required: AND
and this is my code
try{
String sql = "Select id,nama,grup,tanggal from kuli where tanggal between '"+ctgl.getText()+"' 'AND' '"+ctgl1.getText()+"'";
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
jTable1.setModel(DbUtils.resultSetToTableModel(rs));
}
catch(Exception e)
{
System.out.println(e);
}
The SQL should be like this:
String sql = "Select id, nama, grup, tanggal from kuli where tanggal between #" + ctgl.getText() + "# and #" + ctgl1.getText() + "#";
and ctgl.getText() and ctgl1.getText() must return strings formatted as: 2016/11/05
You are not passing proper date for ctgl.getText(), because which the SQL query is failed to retrieve the data. Also, do not use the 'AND' with quotes.
You need to ensure that you are passing the correct date format.
Also, it is NOT recommended to use the prepareStatement like this (i.e., in your code formed the sql using string concatenations) which will allow the cross site scripting, rather the best practice is to use prepareStatement.setString(), setDate(), etc.. methods,
You can look here about cross site scripting.
Two problems:
It looks like your SQL syntax is broken. There should not be quotes around the AND keyword.
You should not be embedding the parameter values into the SQL like that. Instead, you should be using a PreparedStatement and place-holder parameters.
Using PreparedStatement has a number of advantages:
It means that you don't need figure out how to quote values.
It means that you don't need figure out the correct syntax for date/time literals.
It means that you don't need to worry about SQL injection attacks.
The last one is really important if the parameter values come from a source that you cannot completely trust.
More information:
SQL injection
SQL Injection Prevention Cheat Sheet

java.sql.SQLException: ORA-01843: not a valid month (Working in SQL DEVELOPER and doesn't work in JAVA)

I have a table in database that contains the 'Date_transaction' column his type is varchar.
In my Code JAVA, I create a SQL query via several conditions.
When I debug in Eclipse the query generated is like this:
SELECT *
FROM Transaction where 1=1
AND (to_date(Date_transaction,'YYYY/MM/DD HH:MI:SS') between '16/01/01' and '16/02/29')
AND projet = 'Project name'
AND nomtranche = 'tranche name' AND voletctrl = 'volet name'
AND (numeroimmeuble BETWEEN 1 AND 100)
AND validation = 1
AND statutDocNormal = 'statut'
AND numeroAppartement = 14
order by DateTrasaction DESC;
I execute this query in SQL DEVELOPER, the query is executed successfully without any error.
But in my code Java I get this Error : java.sql.SQLException: ORA-01843: not a valid month.
When I want to generate the query, I use this method to convert my date, this I spend in parameter (In the query it's : 16/01/01 and 16/02/29):
public static String parseDate2(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("yy/MM/dd");
String dt = sdf.format(date);
return dt;
}
I try this answer but it's not working.
You are relying on the session's NLS_DATE_FORMAT, which is set differently in the client and probably indirectly via your Java locale. Use explicit conversion with a specific format mask:
... between to_date('16/01/01', 'RR/MM/DD') and to_date('16/02/29', 'RR/MM/DD') ...
But it would be better to use four-digit years and YYYY (remember Y2K?), or date literals - those those don't work with variable values.
This also looks wrong:
to_date(Date_transaction,'YYYY/MM/DD HH:MI:SS')
If `date_transaction is already a date then you are implicitly converting it to a string and then back to a date, which is pointless and dangerous. And then possibly back to a string to compare with your fixed values. If it is a string then it shouldn't be. Either way you need HH24 rather than just HH so you can distinguish between AM and PM.
If it is a date you need:
...
date_transaction between to_date('2016/01/01', 'YYYY/MM/DD')
and to_date('2016/02/29', 'YYYY/MM/DD')
...

Replace Timestamp placeholder in SQL string

Here is the scenario:
I have a sample SQL query like:
SELECT ID, NAME FROM MYTABLE WHERE DATE = &Date
I wanted to replace this &Date at run time based on certain conditions. So I have a utility class which provides the actual Timestamp.
Timestamp timeStamp = Util.getTimeStamp("16102014 03:40:06")
Problem is while I am trying to replace it. If I replace it as a timeStamp.toString() [Not the right way to do it, just for testing I did], its getting replaced but my query became Invalid and I am getting SQL exception (ORA-01861: literal does not match format string).
What I wanted to achieve is I want to replace the place holder with timestamp value and execute the query.
Constraints
I can not use PreparedStatement set values as the query can be any arbitary query and I do not have prior information about the clause.
Any help is appreciated.
Since we are in "String" land, this is a "String" solution:
Timestamp timeStamp = Util.getTimeStamp("16102014 03:40:06")
SimpleDateFormat format = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss''");
String formattedDate = format.format(timeStamp);
sql = sql.replace("&Date", formattedDate);
Note: The double '' in the date format means produce a single quote in the output (a single quote is the delimiter for literal text in a date format).
Note also that because you're not using a driver, the character used to quote the text is database-dependant. This solution assumes that a single quote may be used for quoting a literal, but if your database requires a double quote ", the format should be "\"yyyy-MM-dd HH:mm:ss\"",
I think it should be like this
SELECT ID, NAME
FROM MYTABLE
WHERE DATE = TO_TIMESTAMP(&Date, 'yyyy-mm-dd hh:mm:ss.fffffffff')

java.sql.SQLException: ORA-01843: not a valid month

I am getting the following error when inserting data into my oracle database.
java.sql.SQLException: ORA-01843: not a valid month
In database date is as: dd-MMM-yy (06-MAR-12)
I am converting 06-03-2012 to dd-MMM-yy by the following method:
String s="06-03-2012";
String finalexampledt = new SimpleDateFormat("dd-MMM-yy").format(new SimpleDateFormat("dd-MM-yyyy").parse(s));
So i got 06-Mar-12 which is same as the above database date format still i am getting the error. I am inserting as:
in index.jsp
String todaydate="";
Calendar calendar1 = Calendar.getInstance();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
todaydate = dateFormat.format(calendar1.getTime());
<input type="text" name="datename" value="<%=todaydate%>"/>
in servlet(doPost)
String s=request.getParameter("datename");
PreparedStatement ps=con.prepareStatement("insert into tablename(rest_dt, othercolname) values (to_date(?, 'dd-mm-yyyy'), ?)");
ps.setString(1, s);
ps.setString(2, otherstringdata);
int rs=ps.executeUpdate();
Any idea please
so make
("insert into mytablename (rest_dt) values to_date(?, 'DD-MM-YYYY')");
Try this
TO_DATE(?, 'DD-MM-YYYY','NLS_DATE_LANGUAGE = American')
// gets from Oracle docs
The datatype of your rest_dt columns is a DATE, so you need to supply one. You can use the TO_DATE function to convert a string to an Oracle DATE, so your insert statement
insert into tablename(rest_dt, othercolname) values (to_date(?, 'dd-mm-yyyy'), ?)
is fine.
Just make sure the string value you bind to your first ?-variable is in the format dd-mm-yyyy. And don't convert or format that value yourself: the TO_DATE function does that part.
There is no need to anything about session settings like nls_date_language here, since you have wisely chosen to use a language agnostic setting for the month with your MM mask (instead of MON).
Regards,
Rob.
Problem is that oracle uses NLS_DATE_LANGUAGE to get the current name of the month. So you should do
select * from nls_session_parameters
and check if you have the correct values. You can also check with the following select which name you get for the month
select TO_CHAR(TO_DATE('01-03-01', 'DD-MM-YY'), 'MON') from dual
I really don't understand why you insert the variable as a string value. Just use a date type (do the conversion on the client) in java and insert it without converting. If you really want to insert it as a string I would use a conversion to something like dd-MM-yyyy and insert it with TO_DATE(, 'DD-MM-YYYY').
Edit:
Do the conversion of the date on the client and use
ps.setDate(2, <yourDate>);
The same issue faced while running big query (multiple union) in Java and issue not with actual input since I have properly converted the with to_date('30-06-2021', 'dd-MM-yyyy') and found issue is with the date1 in query.
e.g.
select a,b,c from table1 where date1='31/12/2015'and date2=<actual input>
union
select a,b,c from table2 where date1='31/12/2015'and date2=<actual input>
union
select a,b,c from table3 where date1='31/12/2015'and date2=<actual input>
.
.
date1 also should be convert to to_date like below
e.g.
select a,b,c from table1 where date1=to_date('31/12/2015', 'dd-MM-yyyy') and date2=<actual input>
Hence issue resolved. My suggestions is, if you are getting such issues check the date part in the query and mention with to_date.
Java code:
#Autowired
private NamedParameterJdbcTemplate namedJdbcTemplate;
List<ResponseDTO> list = new ArrayList<>();
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("value1", dto.getValue1());
params.addValue("value2", dto.getValue2());
list = namedJdbcTemplate.query(SQL_QUERY, params, new CustomValueMapper());
Its purely only my own experience. Click up vote if it helps.
java.time and JDBC 4.2
Don’t transfer a date as a string to or from your database. Transfer a proper date object. I am assuming that your JDBC driver is at least JDBC 4.2 compliant. About all drivers are these days. In this case LocalDate is the type to use for dates, both in your Java program and in the transfer to the database.
So what you basically need is this:
LocalDate date = LocalDate.of(2012, Month.MARCH, 6);
PreparedStatement ps = con.prepareStatement(
"insert into tablename(rest_dt, othercolname) values (?, ?)");
ps.setObject(1, date);
ps.setString(2, otherstringdata);
int rs = ps.executeUpdate();
If you are receiving your date as string input from JSP, immediately parse it into a LocalDate object. There’s no need to wait until you need to put it into your database.
String inputString = "06-03-2012"; // Meaning 6 March 2012
LocalDate date = LocalDate.parse(inputString, DATE_PARSER);
I have been using this formatter:
private static final DateTimeFormatter DATE_PARSER
= DateTimeFormatter.ofPattern("dd-MM-uuuu", Locale.ROOT);
Links
Oracle tutorial: Date Time explaining how to use java.time.
Related question: Insert & fetch java.time.LocalDate objects to/from an SQL database such as H2

Categories