2

I need to check the between condition for two numbers in the tables but the column in oracle DB has string values .

I tried the following query , nothing helped me

select * from  sys.employee_infor where  to_number(emp_number) between 1200 and 2400;

select * from  sys.employee_infor where (emp_number) >= to_char(1200) and (emp_number)  <= to_char(2400);

select * from  sys.employee_infor where  to_number(emp_number) between '1200' and '2400';

Received error as :

ORA-01722: invalid number

My Emp_number column be like as,

enter image description here

4
  • 3
    Could you provide some sample data? why will you use string type store number value in emp_number column? Commented Jan 22, 2019 at 8:07
  • 4
    Consider not using SYS schema for your own data. SYS (and SYSTEM) are special, leave them alone. If you do something unexpected, you might destroy the database. Create another user and do whatever you're doing there. Commented Jan 22, 2019 at 8:12
  • 3
    NEVER, ever create your own tables in the SYS or SYSTEM schema. Create a regular user and create your tables there. Do NOT use SYS or SYSTEM for your application ar anything else than doing DBA work. Just don't Commented Jan 22, 2019 at 8:53
  • My Column will be like this Commented Jan 22, 2019 at 12:57

3 Answers 3

2

The safer solution is to use CASE:

SELECT *
FROM sys.employee_infor
WHERE CASE WHEN NOT REGEXP_LIKE(emp_number, '\D') THEN TO_NUMBER(emp_number) END BETWEEN 1200 AND 2400
Sign up to request clarification or add additional context in comments.

2 Comments

REGEXP_LIKE is taking long time to run the query , I need to include this sub query into the main query and Sys is just a example one the user name is different from sys.Please help me to fix the issue
The correct solution is to store numbers as numbers. Rest are just workarounds. You could try using a more efficient regex e.g. CASE WHEN REGEXP_LIKE(emp_number, '^\d{1,10}$') THEN TO_NUMBER... or add another filter e.g. WHERE emp_number BETWEEN '0' AND '9' AND CASE .... Or use the on conversion error solution in the other answer.
1

It is likely that you have data in the employee number column that cannot be converted to a number.

Assuming that the employee number is an integer value, the following query will show you the offending rows :

select * from sys.employee_infor where regexp_like(emp_number, '[^0-9]');

You can use that where clause in your query to ignore badly formatted data :

select * from (
    select * from sys.employee_infor where not regexp_like(emp_number, '[^0-9]')
) where  to_number(emp_number) between 1200 and 2400

PS : as you are looking to compare numbers, not strings.

Another solution is to use the DEFAULT ... ON CONVERSION ERROR option of function TO_NUMBER(), which is available starting Oracle 12c R2. With this option conversion errors are trapped and a default value is returned instead of throwing an error :

select * 
from sys.employee_infor 
where to_number(emp_number default 0 on conversion error) between 1200 and 2400

Comments

0

Under many circumstances, this will work:

where emp_number >= '1200' and emp_number <= '2400'

or:

where emp_number >= '1200' and emp_number <= '2400' and
      length(emp_number) = 4

This is not exactly the same, because it is using string comparisons and not numeric comparisons. On the other hand, it can take advantage of indexes.

1 Comment

Thanks for the suggestion , But when I use the single condition it returns the value but using the two condition nothing was returned . Also What if the comparison between '100' and '1000'

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.