ORA-01722: invalid number - getting this error - sql

I am trying to execute below in oracle sql developer
select code, case when (code = 'SS') then 1 else to_number(code) end as code_modified
from pxrptuser.WBS
But I am getting error.
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause: The specified number was invalid.
*Action: Specify a valid number.
The output should be -
code code_modified
D0DV-IMS null
gWBS null
8 8
1 1
SS 1
Please help me with the actual query

You have strings in your data that cannot be converted to numbers (other than "SS").
Starting Oracle 12.2, you can use the on conversion error clause to to_number() to return null for invalid values:
select code,
case
when code = 'SS' then 1
else to_number(code default null on conversion error)
end as code_modified
from pxrptuser.WBS
In earlier versions, one alternative uses a regex. If your numbers have no decimal part, as showned in your data, it is simpler:
select code,
case
when code = 'SS' then 1
when not regexp_like(code, '\D') then to_number(code)
end as code_modified
from pxrptuser.WBS

Related

Oracle SQL export to csv show error: ORA-01722: invalid number

table_a table_b
-------------- ----------
product,amount,pcode rounding,pcode
-------------- ----------
apple,100.00,001 0.02,001
orange,150.02,001 -0.02,001
output
----------
apple,100.02
orange,150.00
select a.product||','||sum(a.amount)+b.rounding from table_a a,table_b b
where a.pcode=b.pcode
group by a.product,b.rounding
Hi , I trying to spooling this query to csv format, but showing error:
ORA-01722 invalid number.
when I remove +b.rounding then no issued at all, may I know how to use sum(a.amount)+b.rounding in my query ?
your kinds assist is much appreciated.
The error has nothing to do with "export to csv" or with aggregation. You can reproduce it very simply, like this:
select 'a' || 1 + 3 as result from dual;
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause: The specified number was invalid.
*Action: Specify a valid number.
The reason is very simple: concatenation (the || operator) has the same precedence as addition (+). Since in your formula concatenation comes first, it is performed first. In my example, the number 1 is converted (implicitly) to the string '1' and concatenated to 'a', resulting in 'a1'. Then this must be added to 3. To do that, Oracle tries to convert 'a1' (implicitly) to number, and obviously that fails, with the same error you observed.
If you expected the result to be the string 'a4' (in my example), the solution is trivial: use parentheses.
select 'a' || (1 + 3) as result from dual;
RESULT
------
a4
The same applies to your situation.
Note that the following works - showing that || and + have the same precedence; concatenation is not stronger than addition, they are simply performed in order, left to right.
select 1 + 3 || 'a' as result from dual;
RESULT
------
4a
Here we don't need parentheses, because 1 + 3 = 4, and then that is converted to the string '4' and then 'a' is concatenated to it.

how to use case with count function in oracle plsql

here is the query, i want to use case statement with count function in oracle.
Select case when count(*) > 0 then 'doSomething' else 'doSomething'
from student where student_name='faizan ahmed' and student_father='ahmed' and UPPER(student_dob)=UPPER('01-FEB-19');
please help me out, using plsql code.
ORA-00905: missing keyword
00905. 00000 - "missing keyword"
For this purpose, use exists instead:
Select (case when exists (select 1
from student
where student_name = 'faizan ahmed' and
student_father = 'ahmed' and
upper(student_dob) = upper('01-FEB-19');
then 'doSomething'
else 'doSomethingElse'
end)
from dual;
EXISTS is usually more efficient than a count, because it can stop at the first matching row instead of aggregating the whole table.
You're missing an END for CASE:
SELECT CASE WHEN COUNT (*) > 0 THEN
'doSomething'
ELSE 'doSomething'
END --> This
FROM student
WHERE student_name = 'faizan ahmed'
AND student_father = 'ahmed'
AND UPPER (student_dob) = date '2019-02-01' -- No! UPPER ('01-FEB-19');
It is easier to spot if you format code you write.
Apart from that, STUDENT_DOB seems to be a date. If so, then don't compare it to a string (because '01-feb-19' IS a string) but to a date (date '2019-02-01' - it is a date literal, consists of the date keyword and yyyy-mm-dd value).
Also, it is strange that you used UPPER with that "date" string, but all your names are lowercase. Hm?

Invalid number error while executing query

I need your help in an error which I'm getting, I'm using the below query in order to see the average of a percentage column in my table, but it is giving me the below error message:
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause:
*Action:
Query:
SELECT 'Skybox' as Platform,avg(PER_OF_VIOLATING_RULES) as
ComplianceCalculation from table_name
Values in the PER_OF_VIOLATING_RULES column:
PER_OF_VIOLATING_RULES
32.08%
55.77%
54.19%
54.84%
16.13%
23.22%
29.50%
5.56%
48.50%
56.04%
PER_OF_VIOLATING_RULES column is a varchar2 Datatype.
Try to replace the % sign:
SELECT 'Skybox' as Platform,avg(replace(PER_OF_VIOLATING_RULES, '%', '')) as ComplianceCalculation from table_name

Invalid number error in where clause

I am executing a query in Oracle database. The column and everything is correct but I am getting an Invalid Number error for below query:
select COUNT(*) AS "COUNT" from NE.STRUCT B
where B.STRUCT_TYPE in ('IDC')
and NET_ENTITY_ID is not null
and length(NET_ENTITY_ID) = 18
AND regexp_like(SUBSTR(NET_ENTITY_ID,15,1),'[^A-Z]')
and TO_NUMBER(SUBSTR(NET_ENTITY_ID,(length(NET_ENTITY_ID) -3), 4)) < 6000;
NET_ENTITY_ID field has only one data ABCDEFGHXXXXNB0001.
But not necessary that it will always be having one data. This is just for resolving the issue I am considering only this.
Error Message:
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause: The specified number was invalid.
*Action: Specify a valid number.
The problem is that Oracle -- and any other database -- does not guarantee the order of evaluation of clauses in a WHERE. You can get around this using CASE:
where B.STRUCT_TYPE in ('IDC') and
NET_ENTITY_ID is not null and
length(NET_ENTITY_ID) = 18 AND
regexp_like(SUBSTR(NET_ENTITY_ID, 15, 1), '[^A-Z]') and
(CASE WHEN regexp_like(SUBSTR(NET_ENTITY_ID,(length(NET_ENTITY_ID) -3), 4), '^[0-9]{4}$'
THEN TO_NUMBER(SUBSTR(NET_ENTITY_ID,(length(NET_ENTITY_ID) -3), 4))
END) < 6000;
You need to ensure that the last 4 chars are numeric before using TO_NUMBER on them.
This will do it:
select COUNT(*) AS "COUNT" from
( SELECT * FROM NE.STRUCT B
where B.STRUCT_TYPE in ('IDC')
and NET_ENTITY_ID is not null
and length(NET_ENTITY_ID) = 18
AND regexp_like(SUBSTR(NET_ENTITY_ID,15,1),'[^A-Z]')
AND regexp_like(SUBSTR(NET_ENTITY_ID,-4),'[0-9]')
)
where TO_NUMBER(SUBSTR(NET_ENTITY_ID,-4)) < 6000;
NB I simplified your SUBSTR for obtaining the last 4 characters.

inconsistent datatypes: expected - got CHAR

I have a senario where, I have the following Where Clause in my query. I am using Oracle 11g (11.2.0.1)
select * from aTable WHERE (attribute_name IN
(SELECT * FROM TABLE(CAST(:pbindvar AS CHARTABLETYPE)))or :pbindvar IS NULL)
The value for this bind variable is a array, but when I am trying to pass a null value to this bindvariable I am getting the following error
Expected - Got Char Error
Could anyone please let me know how am I supposed to pass a null value to this Bind variable so that the query will return me all the set of rows without applying the where condition.
Stack trace is as follows
ORA-00932: inconsistent datatypes: expected - got CHAR
00932. 00000 - "inconsistent datatypes: expected %s got %s"
*Cause:
*Action:
I tried the following as well but with no luck still getting the same exception
I tried with the conditional where clause still getting the same error
WHERE (CASE WHEN :pbindvar is NULL THEN 1
WHEN attribute_name IN (SELECT * FROM TABLE(CAST(:pbindvar AS CHARTABLETYPE))) THEN 1
ELSE 0
END) = 1
If I change the second condition where clause as mentioned below, the query is returning with all rows
WHERE (CASE WHEN :pbindvar is NULL THEN 1
WHEN attribute_name IN (:pbindvar) THEN 1
ELSE 0
END) = 1
Sample Query using hr schema
select * from Departments where department_name in (Select * from table(cast(:pbindvar as CHARTABLETYPE))) or :pbindvar is Null;
create query for type
create or replace type chartabletype
as table of VARCHAR2(4000);
The issue occurs only when the null is passed to bind variable