ORA-01722: invalid number error - sql

I am running the below mentioned query in my Oracle client and i am getting
ORA-01722: invalid number
error. I know the issue is due to the TAG_VALUE column being of type "varchar2" and i am converting it to number and then using that field in where clause. I have tried using "CAST" function but that is also not helping.
If i run the query neglecting the last where condition with code WHERE (P.TAG_VALUE > '100') then i am getting the result but including the last where clause gives me error.
SELECT DISTINCT
count(P.CREATED_DATETIME)
FROM
(
select OUTPUT_TAG_ID,TO_NUMBER(TAG_VAL,'9999.99') AS
TAG_VALUE,TAG_VAL_TS,CREATED_DATETIME
from OV80STG.PRCSD_DATA_OUTPUT_ARCHIVE
where MODEL_CODE='MDLADV1538'
AND TAG_VAL <> 'U_Transfer_rate'
) P
WHERE
(P.TAG_VALUE > '100')
Any suggestion will be appreciated. Thanks.

Remove the single quotes from around the value in the where, you don't need them when its an integer. query will be like this:
SELECT DISTINCT
COUNT(P.CREATED_DATETIME)
FROM
(
SELECT
OUTPUT_TAG_ID,
TO_NUMBER(TAG_VAL, '9999.99') AS TAG_VALUE,
TAG_VAL_TS,
CREATED_DATETIME
FROM OV80STG.PRCSD_DATA_OUTPUT_ARCHIVE
WHERE MODEL_CODE = 'MDLADV1538'
AND TAG_VAL <> 'U_Transfer_rate'
) P
WHERE(P.TAG_VALUE > 100);

TO_NUMBER function returns a numeric value so, as mentioned in comment, you shouldn't compare it with string value.

I solved the issue by including outer where clause inside the subquery and then I got the required result without any error.

Related

Error with group by in DB2 - SQLSTATE 42803

I've got a SQL script and its failing. This is what it looks like:
SELECT P.SOORT,P.TYPEBETALING, P.MIDDELCODE, P.HOEVEELHEID, P.EENHEID, P.BEDRAG,P.MIDDEL
FROM DAAO01.BETALINGEN as A join
DAAO01.KLANTEN P
on p.KLANT_ID = 1
GROUP BY P.TYPEBETALING
ORDER BY P.TYPEBETALING
When I execute this I get an error:
COLUMN OR EXPRESSION IN THE SELECT LIST IS NOT VALID. SQLCODE=-122, SQLSTATE=42803, DRIVER=4.18.60
What am I doing wrong?
It is quite difficult to tell what you're trying to do without seeing your data.
But the error is saying that you have not specified how you are going to deal with the rest of the fields in your Group by aggregation:
P.SOORT, P.MIDDELCODE, P.HOEVEELHEID, P.EENHEID, P.BEDRAG, P.MIDDEL
If they're numbers, then you could sum them or take the avg etc.
If they're strings, then you either need to group by them or remove them from your selection.

ORA-01722- Invalid Number

I have a query in the package throwing error
ORA-01722 : invalid number.
I tried many ways but no luck.
select h.column
from table1 h,table2 c
where c.created_date='17-MAY-17'
and nvl(c.acct_nmbr,0)=nvl(to_number(h.v_acct_num),0)
c.acct_nmbr is of NUMBER(19,0)
h.v_acct_num is of varchar2(4000 byte)
Please suggest me the solution
If you are using Oracle 12.2 or higher then you can use the TO_NUMBER with ON CONVERSION ERROR clause as follows:
SELECT
H.COLUMN
FROM
TABLE1 H
JOIN TABLE2 C
ON NVL(C.ACCT_NMBR, 0) = NVL(TO_NUMBER(H.V_ACCT_NUM DEFAULT -999 ON CONVERSION ERROR), 0)
-- use any number which is impossible in your column
-- so that it do not match any random records.
WHERE
C.CREATED_DATE = DATE '2017-05-17';
Note:
Use standard ANSI joins
Use DATE literal wherever you want to convert string to date or TO_DATE function
Cheers!!
Obviously v_acct_num column contains non-numeric values. to_number() function has restriction that the value in the argument shouldn't contain any non-numeric character, otherwise the system hurls with ORA-01722 : invalid number. If you're sure about the data matches when non-numeric characters are extracted then use regexp_replace(t2.v_acct_num,'[^[:digit:]]') within the collation of the join's on clause :
select t2.column
from table1 t1
join table2 t2 on nvl(t1.acct_nmbr,0) = nvl(regexp_replace(t2.v_acct_num,'[^[:digit:]]'),0)
where t2.created_date = date'2017-05-17'
Use ANSI-92 standard for Join, and ISO-8601 standard for date syntaxes.
Identify what data is non-numeric:
select * from table1 h
where regexp_like(h.v_acct_num, '[^0-9]')
and delete them
.
Hope it helps.

Error when aggregating due to conversion from varchar to bigint

Situation:
I want to aggregate a value from a table but i get the following error :
Error converting data type varchar to big int.
I've been reading countless of different solutions online but they don't seem to solve it.
Current query;
So based on the error message, i simply added the CAST function but it still doesnt work.
SELECT
base.target_date AS target_date
, base.game_id AS game_id
, base.device AS device
, ISNULL(CAST(SUM(use_point.point) AS bigint),0) AS result
FROM
cte AS base
LEFT JOIN cte2 AS use_point
ON base.target_date = use_point.target_date
AND base.game_id = use_point.device
AND base.device = use_point.device
GROUP BY
base.target_date
, base.device
, base.game_id
WITH ROLLUP
GO
I'm presuming that use_point.point is a VARCHAR, in which case simply change where you put your CAST statement:
, ISNULL(SUM(CAST(use_point.point AS bigint)), 0) AS result
Note that the CAST now takes place before the SUM.
Use TRY_CAST() instead. And it needs to be an argument to the SUM():
SELECT base.target_date, base.game_id, base.device,
COALESCE(SUM(TRY_CAST(use_point.point as bigint)), 0) as result
FROM . . .
Note that your column aliases are redundant, because you are assigning the default aliases.
You should also fix the data. Don't store numeric values as strings. To find the bad data, you can use:
select points
from use_points
where try_convert(points as bigint) is null and
points is not null;

Hive - SELECT inside WHEN clause of CASE function gives an error

I am trying to write a query in Hive with a Case statement in which the condition depends on one of the values in the current row (whether or not it is equal to its predecessor). I want to evaluate it on the fly, this way, therefore requiring a nested query, not by making it another column first and comparing 2 columns. (I was able to do the latter, but that's really second-best). Does anyone know how to make this work?
Thanks.
My query:
SELECT * ,
CASE
WHEN
(SELECT lag(field_with_duplicates,1) over (order by field_with_duplicates) FROM my_table b
WHERE b.id=a.id) = a.field_with_duplicates
THEN “Duplicate”
ELSE “”
END as Duplicate_Indicator
FROM my_table a
Error:
java.sql.SQLException: org.apache.spark.sql.AnalysisException: cannot recognize input near 'SELECT' 'lag' '(' in expression specification; line 4 pos 9
Notes:
The reason I needed the complicated 'lag' function is that the unique Id's in the table are not consecutive, but I don't think that's where it's at: I tested by substituting another simpler inner query and got the same error message.
Speaking of 'duplicates', I did search on this issue before posting, but the only SELECT's inside CASE's I found were in the THEN statement, and if that works the same, it suggests mine should work too.
You do not need the subquery inside CASE:
SELECT a.* ,
CASE
WHEN prev_field_with_duplicates = field_with_duplicates
THEN “Duplicate”
ELSE “”
END as Duplicate_Indicator
FROM (select a.*,
lag(field_with_duplicates,1) over (order by field_with_duplicates) as prev_field_with_duplicates
from my_table a
)a
or even you can use lag() inside CASE instead without subquery at all (I'm not sure if it will work in all Hive versions ):
CASE
WHEN lag(field_with_duplicates,1) over (order by field_with_duplicates) = field_with_duplicates
THEN “Duplicate”
ELSE “”
END as Duplicate_Indicator
Thanks to #MatBailie for the answer in his comment. Don't I feel silly...
Resolved

Error on query with "Replace"

I Have an error on a oracle server but I don't understand why is not work.
I use the software oracle sql developer.
The query is:
SELECT * FROM TestView WHERE REPLACE(TestView.Row2, '.', ',') > 0 ;
The value who is in TestVue.Row2 : '46.08','-46.47','1084.05','66500',...
"TestView" is a view who check to return a row without empty value
When I Execute the query I have always an error who says:
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause:
*Action:
Thanks for your help
Zoners
You have a row in your table, which cannot be parsed into number format. Most likely it is a blank column.
SELECT * FROM TestVue WHERE TestVue.Row2 IS NULL ;
Use a NVL Function to avoid errors caused by null field and a TO_NUMBER function to cast into a number before comparision with zero
SELECT * FROM TestView WHERE TO_NUMBER(REPLACE(NVL(TestView.Row2,'0'), '.', ',')) > 0 ;
You should be able to find the row with something like:
select Row2
from TestVuw
where length(trim(translate(Row2, '+-.,0123456789', ' '))) = 0
Of course, this allows multiple +, -, ., and ,. It can be further refined using a regular expression, but this usually works to find the bad ones.