Update table by case ORA-01722 Invalid Number - sql

I am trying to update a table's column based on the value of of two other columns.
For some reason, I am getting ORA-01722: invalid number
UPDATE TableT SET
Col = (CASE when PER in ('1234','2134','2314','3214') AND TYPE = 4 then '4'
when PER in ('34','104','1004') AND TYPE = 4 then '35'
when PER in ('124','1204','2014') AND TYPE = 4 then '36'
ELSE 'Missing'
END);

The only way this statement can fail with ORA-01722 is if Col is a numeric column. '4', '35' and '36' can be automatically converted to a number. However, if none of the case conditions are met, and you end up evaluating the else branch, it will return the string Missing that cannot be converted to a number.
One way to deal with it could be to use null, which was designed to signify a missing value instead:
UPDATE TableT SET
Col = (CASE when PER in ('1234','2134','2314','3214') AND TYPE = 4 then 4
when PER in ('34','104','1004') AND TYPE = 4 then 35
when PER in ('124','1204','2014') AND TYPE = 4 then 36
ELSE NULL
END);

Related

How do I update a row to be valid if the other columns match a certain DataType?

I have a table with 5 rows. An ID column, 2 varchar columns, an isValid Column and a ValidationFailure column. The data for 2 columns are updated with data from an excelsheet through code. The data types while inserting for 2 columns are varchar. I now have to check if these 2 columns match MONEY type and if there is an issue update column isValid to false with ValidationFailure column a concatenation of the column names that fail the test.
I am using an update statement with a where clause. But I am unable to have a concatenation of the column names that fail the condition.
I am using the following update statement :
update t
set t.isValid = 0
from table t
where IsNumeric(t.col1+'e0') = 0 or IsNumeric(t.col2+'e0') = 0
How can I update t.ValidationFailure column with the column names that failed the condition?
If both fails then the column value can be col1,col2
This can be achieved with a CASE
update t set
t.isValid = 0,
t.ValidationFailure =
case
when IsNumeric(t.col1+'e0') + IsNumeric(t.col2+'e0') = 0 then 'both'
when IsNumeric(t.col1+'e0') = 0 then 'col1'
when IsNumeric(t.col2+'e0') = 0 then 'col2'
else 'unknown'
end
from table t
where IsNumeric(t.col1+'e0') = 0
or IsNumeric(t.col2+'e0') = 0

type cast in Case statement

Segment
1
2
3
4
NUll
5
I want to impute 'Other' if the Segment value is null
expected output
Segment
1
2
3
4
Other
5
i have tried
select
case when segment is null then 'Other' else segment end as segment
from table;
It says invalid input syntax for type "numeric":Other
The case expression returns a single type. The problem is that segment is a number, but 'Other' is a string. The expression has to make a choice, and it chooses the numeric type (following standard SQL rules).
This is simple to fix. Just cast segment:
select (case when segment is null then 'Other' else segment::text end) as segment
from table;
It would be more natural to write this query using coalesce():
select coalesce(segment::text, 'Other') as segment
from table;
select
case when CAST(segment AS CHAR) IS NULL then 'Other' else CAST(segment AS CHAR) end as segment
from table

String data right truncation DB2 error

I am receiving the error "String data right truncation" on db2 when I use this query
SELECT BILL_NUMBER, 'PAPERWORK BUT NOT COMPLETE', 'NONE', NULL, '00000',NULL,NULL,TOTAL_CHARGES, NULL FROM TLORDER WHERE
CURRENT_STATUS NOT IN ('COMPLETE','APPRVD','PAPERWISE','BILLD','EDIBILLED','CANCL') AND BILL_TO_CODE NOT LIKE CASE WHEN :INCLUDE_DED = 'No' THEN 'ROCD%' ELSE '1234kkh5656' END
AND EXISTS (SELECT 1 FROM LIST_CHECKIN_AUDIT A WHERE A.BILL_NUMBER = TLORDER.BILL_NUMBER FETCH FIRST 1 ROW ONLY)
AND SITE_ID = :SITE AND DELIVER_BY_END >= CURRENT TIMESTAMP - 3 MONTHS AND COALESCE(PICK_UP_DRIVER,'') = '' AND '00000' =:DRIVER_ID
However when I suppress this line I do not get the error.
AND BILL_TO_CODE NOT LIKE CASE WHEN :INCLUDE_DED = 'No' THEN 'ROCD%' ELSE '1234kkh5656' END
Thanks in advance!
I'd venture to guess that this happens when the value of the :INCLUDE_DED host variable exceeds 2 bytes in length. You do not supply the variable data type, so the query compiler derives it from the right side of the comparison, where the literal 'No' has the length of 2 bytes. If you then assign a value like 'Yes' to the host variable it has to be truncated.
Consider adding an explicit type information to the host variable reference, e.g.:
...WHEN CAST(:INCLUDE_DED AS VARCHAR(10)) = 'No'...
Use the data type appropriate for the range of possible values.
I would first check the datatype of the bill_to_code. You are returning '1234kkh5656' that may exceed the length of the datatype.

SQL Server : ignore strings in SUM function

I do a sum function over a column. But the column can have string values also. I want SQL Server to ignore the string values and sum only the string values.
Eg: column can have values like 16000Euro or 2588, or 3671.
The input is from user and I cant change validation in the app to integer
I have tried this but still shows error:
SUM(CASE WHEN Type_New = 202 AND ISNUMERIC(Summe) = 1
THEN Summe
ELSE 0
END) AS total_Euro
So how can I ignore the string values when doing sum operation?
The error I get is:
Error converting nvarchar value '2588. 'in the int data type.
EDIT: I want SQL to ignore such string values and sum what it can.. The main aim is that Query should not throw any error
Try the below Query, it will work perfectly :)
SELECT SUM(CASE WHEN Type_New = 202 AND ISNUMERIC(Summe + '.0e0') = 1
THEN Summe
ELSE 0
END) AS total_Euro FROM TableName
IsNumeric returns 1 if the varchar value can be converted to ANY number type (includes int, bigint, decimal, numeric, real & float) Values like 1e4,1., 2.0 will create the issue if the above check to bypass these values is not added.
You should not name column same as a keyword in SQL Server , if this cannot be avoided you can escape column name by enclosing in square bracketes [Sum] as shown below
SELECT SUM(CASE WHEN Type = 202 AND ISNUMERIC([Sum]) = 1 THEN [Sum] ELSE 0 END) AS total_Euro
Try this
SUM(CASE WHEN Type = 202 AND case when Sum not like '%[^0-9]%' THEN Sum END ELSE 0 END) AS total_Euro
or
SUM(CASE WHEN Type = 202 AND ISNUMERIC(Sum+'.e0') = 1 THEN Sum ELSE 0 END) AS total_Euro
Try this:
SUM (CASE
WHEN Type_New = 202 AND ISNUMERIC(Summe) = 1 THEN CAST(summe AS DECIMAL(9,2))
ELSE 0 END) AS TotalEuro
I don't know if you do this SUM for one column or what, but also you can filter out what you need and then sum:
SELECT SUM(Summe) AS total_Euro
FROM someTable
WHERE Type_New = 202 AND ISNUMERIC(Summe) = 1
ISNUMERIC function considers strings that contain large numeric (e.g., 9223372036854775808), decimals (e.g., 12.4), currency figures (e.g., $123), and floating-point values (e.g., 1E2) to be strings that can be converted to a numeric data type.
Now to calculate Sum you will have to convert string to an integer[ this assumption is based on
sample data you have posted] but fact is string can be numeric but might not be convertible to an integer; the ISNUMERIC function is limited in the sense that it can tell you only whether the string can be converted to any numeric data type.
So if your column doesn't have string data like 1E3 or 12.4 or $123 which are numeric but not integers you can simply cast the target column to int as below and calculate the sum :
select SUM(CASE WHEN Type_New = 202 AND ISNUMERIC(Summe) = 1
THEN CAST(Summe AS INT)
ELSE 0
END) AS total_Euro
FROM test
else you shoudl go for a more generic function which as discussed here..
http://sqlmag.com/t-sql/can-i-convert-string-integer

update varchar field ; Diffrence between using single quotes and with out using

I am using Teradata as database,
Table
sno varchar(10) primary,
number varchar(10)
I was able to update number field like this
update ...
set number = '1'
or
set number = 1
I was able to get correct result in my select query [ had max(number) column ],when I updated second way i.e set number = 1 with out using any cast functions.
using this (i.e set number = '1' ) gives me the wrong result with my select query, with out
using cast functions
can any one explain the difference?
In short , I need difference between
update ...
set number = '1'
or
set number = 1
set number = 1
updates the VARCHAR to '1'
set number = 1
does an automatic Teradata style typecast (right aligned within FORMAT) and sets number to ' 1'.
SELECT (1 (VARCHAR(10))) || '#', FORMAT(1), TYPE(1);
*** Query completed. One row found. 3 columns returned.
*** Total elapsed time was 1 second.
(1||'#') Format(1) Type(1)
----------- ------------------------------ -------------
1# -(3)9 BYTEINT
What do you expect when you query MAX(col)?
For VarChars '9' is greater than '11', if you need numeric comparison you should use a numeric datatype.