2

Im trying to run this below query but its seems to be error

For those data types are varchar

Query

select * 
  from RP_REPORT_TEMP 
 where to_char(START_DATE,'FM DD YYYY HH24:MI:SS AM') 
          >= 'May 01 2016 00:00:00' 
   and to_char(END_DATE,'FM DD YYYY HH24:MI:SS PM') 
          <= 'May 31 2016 11:59:00' 
   and lower(rid) like '%a001%' 
 order by CAST(cid as INTEGER) asc

Table

|RID                 |START_DATE                 |END_DATE                     |
|--------------------|-------------------------- |-----------------------------|
|A001                |May  1 2016 12:00:00:000AM |May  31 2016 12:00:00:000PM  |
|A001                |May  1 2016 12:00:00:000AM |May  31 2016 12:00:00:000PM  |
|A001                |May  1 2016 12:00:00:000AM |May  31 2016 12:00:00:000PM  |

While i tried to execute this query. Query return some error. How can i fix this ?

Error

SQL Error [1722] [42000]: ORA-01722: invalid number
java.sql.SQLSyntaxErrorException: ORA-01722: invalid number
8
  • No idea why you added tags for MySQL or SQL Server since TO_CHAR() does not exist in either DBMS. I've assumed it was an error and removed them. If you're actually looking for a cross-DBMS method to manipulate dates please edit the question. Commented Jun 22, 2016 at 11:42
  • What is the datatype of the following columns, please? START_DATE, END_DATE, CID Commented Jun 22, 2016 at 11:48
  • 2
    @QuestionUser I knew that was the issue. You performing the wrong operations with the datatype you have. Anyways try and remove meridiam indicators since you are using HH24 in your OP and use proper spacing with meridiams indicators Commented Jun 22, 2016 at 11:52
  • 3
    Never, ever store dates or timestamps in varchar columns. Just don't. Commented Jun 22, 2016 at 11:54
  • 1
    @QuestionUser For instance t: TO_DATE( 'January 15, 1989, 11:00 A.M.', 'Month dd, YYYY, HH:MI A.M.', 'NLS_DATE_LANGUAGE = American') That one is not using HH24 plus is specifying the date language (hopefully your defaullt date language is American). Check this docs.oracle.com/cd/B19306_01/server.102/b14200/functions183.htm . Anyways since you table fields are varchar, I recommand they be stored in proper date format (though varchar) then do a to_date to_date comparison (see Avi answer below if you want to use HH24 or Alvaro ansswer if not using HH24 ) Commented Jun 22, 2016 at 12:05

4 Answers 4

1

Why don't you use TO_DATE() on the date instead?

select * from RP_REPORT_TEMP 
where START_DATE >= to_date('May 01 2016 12:00:00 AM','MON DD YYYY HH:MI:SS AM')
  and END_DATE <= to_date('May 31 2016 11:59:00 AM','MON DD YYYY HH24:MI:SS AM')
  and lower(rid) like '%a001%'
Sign up to request clarification or add additional context in comments.

10 Comments

its returns some error like this SQL Error [1858] [22008]: ORA-01858: a non-numeric character was found where a numeric was expected java.sql.SQLDataException: ORA-01858: a non-numeric character was found where a numeric was expected
@QuestionUser I think that it's because you have AM / PM in your table fields. What type are the table fields anyway ?
@KurtMiller i have removed and i tried its not working :(
same error SQL Error [1858] [22008]: ORA-01858: a non-numeric character was found where a numeric was expected java.sql.SQLDataException: ORA-01858: a non-numeric character was found where a numeric was expected @sagi
is this neceesary to change the dateformat in table ? @sagi
|
0

Assuming that START_DATE and END_DATE are actually dates, I can spot two main issues in your code:

  1. Casting every row to string is slow and also prevents Oracle from using indexes (unless you have a carefully built function-based index).

  2. Lexicographical sort (aka "A to Z") does not render meaningful results with dates with "May 1". Just think of what sense this list has: Apr, Aug, Dec, Feb, Jan, Jul, Jun, Mar, May, Nov, Oct, Sep

My suggestions are:

  • Avoid converting dates to string, save for display purposes
  • Use a more solid format when you have to convert from string to date

As a result:

select * 
  from RP_REPORT_TEMP 
 where START_DATE
          >= TO_DATE('2016-05-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
   and END_DATE
          <= TO_DATE('2016-05-31 11:59:00', 'YYYY-MM-DD HH24:MI:SS')
   and lower(rid) like '%a001%' 
 order by CAST(cid as INTEGER) asc

P.S. START_DATE and END_DATE were not dates after all

2 Comments

its returns some error like this SQL Error [1858] [22008]: ORA-01858: a non-numeric character was found where a numeric was expected java.sql.SQLDataException: ORA-01858: a non-numeric character was found where a numeric was expected
Just look at my first sentence: "Assuming that START_DATE and END_DATE are actually dates". I've just seen your edit where you explain they aren't.
0

Try this..

 select * 
      from RP_REPORT_TEMP 
     where TO_date(START_DATE,'MON DD YYYY HH:MI:SS AM') 
              >= to_Date('May 01 2016 12:00:00 AM' ,'MON DD YYYY HH:MI:SS AM') 
       and TO_DATE(END_DATE,'MON DD YYYY HH:MI:SS PM') 
              <= TO_DATE('May 31 2016 11:59:00 AM' ,'MON DD YYYY HH:MI:SS PM') 
       and lower(rid) like '%a001%' 
     order by CAST(cid as INTEGER) asc

select * 
      from RP_REPORT_TEMP 
     where TO_date(START_DATE,'MON DD YYYY HH24:MI:SS') 
              >= to_Date('May 01 2016 12:00:00' ,'MON DD YYYY HH24:MI:SS') 
       and TO_DATE(END_DATE,'MON DD YYYY HH24:MI:SS') 
              <= TO_DATE('May 31 2016 11:59:00' ,'MON DD YYYY HH24:MI:SS') 
       and lower(rid) like '%a001%' 
     order by CAST(cid as INTEGER) asc

9 Comments

it returns some error like this SQL Error [1818] [22008]: ORA-01818: 'HH24' precludes use of meridian indicator java.sql.SQLDataException: ORA-01818: 'HH24' precludes use of meridian indicator
@QuestionUser That's because your format is incorrect. Please give an example of a date in your START_DATE column. ETA: ah, whoops, you already did in your question, sorry!
now returns error like this SQL Error [1861] [22008]: ORA-01861: literal does not match format string java.sql.SQLDataException: ORA-01861: literal does not match format string
No , actually its because of the 00:00:00 . Change it to 12:00:00 and add AM/PM
@Avi , change 00:00:00 to 12:00:00
|
0

This is what your query should look like:

select   * 
from     rp_report_temp 
where    to_date(start_date,'FM Mon DD YYYY HH:MI:SS"FMMon DD YYYY HH:MI:SS":000"AM', 'nls_date_language = english') 
            >= to_date('01/05/2016 00:00:00', 'dd/mm/yyyy hh24:mi:ss')
and      to_date(end_date,'FM Mon DD YYYY HH:MI:SS":000"AM', 'nls_date_language = english') 
            <= to_date('31/05/2016 23:59:59', 'dd/mm/yyyy hh24:mi:ss')
and      lower(rid) like '%a001%' 
order by cast(cid as integer) asc;

Here, I have converted your start and end date columns into a date, based on the fact that a sample string in that column looks like "May 1 2016 12:00:00:000AM" - there's an extra ":000" after the seconds; I'm assuming this is always ":000".

Note how I've made your code nls_date_language parameter independent, by specifically setting that value within the to_date(). This means that if someone else's client has that set to something that's not English, the sql statement will still work for them.

You'll note that I didn't need to do that for the values you're testing, since I changed the format of the string to something that used numbers to represent the months.

You have some fundamental data modelling issues here too - by storing everything as varchar2 you have made a rod for your own back - you've lost all the validation available (what happens if someone puts a string of Feb 30 2015 39:99:99 AM in that column? AWOOGA, AWOOGA, error!). You've made your queries have to work harder (now we've got functions all over the place trying to convert data to the correct datatype).

You should store data in the correct datatype. Dates should be stored as DATE, Timestamps as TIMESTAMP, numbers as NUMBER (with or without specific precision and scale), etc etc.

If your data was stored correctly, then your query would be:

select   *
from     rp_report_temp
where    start_date >= to_date('01/05/2016 00:00:00', 'dd/mm/yyyy hh24:mi:ss')
and      end_date <= to_date('31/05/2016 23:59:59', 'dd/mm/yyyy hh24:mi:ss')
and      lower(rid) like '%a001%'
order by cid asc;

4 Comments

SQL Error [1861] [22008]: ORA-01861: literal does not match format string java.sql.SQLDataException: ORA-01861: literal does not match format string
I've updated the format. Your start and end date columns are in a really odd format. Is the format meant to take care of milliseconds?
SQL Error [1858] [22008]: ORA-01858: a non-numeric character was found where a numeric was expected java.sql.SQLDataException: ORA-01858: a non-numeric character was found where a numeric was expected :(
Then the data in your columns aren't always in the expected format. Or your cid column contains values which aren't numbers. This is the danger you run into when you store data in the wrong datatype. I cannot recommend updating the datatypes of your columns highly enough. Honestly, it'll save you so much grief in the long run!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.