I have column TEXT_INT in my table and I would like convert to DECIMAL using TO_NUMBER Function. Unfortunately I am getting
INVALID NUMBER ORA-722 error.
I doubt it may have characters in it. So Issued below query but there is no alphabets in TEXT_INT.
SELECT *
FROM NANTHA_TABLE
WHERE UPPER(TEXT_INT) != LOWER(TEXT_INT);
Would you please provide an idea to resolve this issue or ways to finding wrong data?
try this:
create function like this:
CREATE OR REPLACE function f_invalid_number(number_field in varchar2) return number as
n_d number;
begin
n_d := TO_number(number_field);
return 0;
exception
when others then
return 1;
end;
/
then you can check invalid data like this:
SELECT *
FROM NANTHA_TABLE
WHERE f_invalid_number(TEXT_INT) =1
This query may help you.
select your_wrong_col ,
case
when trim(TRANSLATE(your_wrong_col ,'0123456789','')) is null
then 'numeric'
else 'not_numeric'
end as your_wrong_col
from YOUR_TABLE
where trim(TRANSLATE(your_wrong_col ,'0123456789','')) is not null;
Finds non-numeric rows.
Please use below query to find records where TEXT_INT column has characters other than number.
select * from NANTHA_TABLE where NOT REGEXP_LIKE(TEXT_INT,'^[0-9]+$')
In case you are expecting more string symbols in your column which should be considered as valid you can include them in the NOT REGEXP_LIKE condition so those columns also don't appear in the query.
eg. If expecting a '-' symbol in the start of the string for some values:
NOT REGEXP_LIKE(COLUMN_NAME, '^-?[0-9.]+$') "
where
'^' Begining
'?' Zero or One occurance
'+' One of More occurance
'$' End of String
Please note i know that the decimals in my above query will be accepted even if counted twice. For that I propose a different solution to count the number of decimals in the string and throw error. If any1 can integrate it with the REGEXP you are most welcome. How to count number of decimals for check.
LENGTH(COLUMN_NAME) - LENGTH(REPLACE(COLUMN_NAME,'.','')) > 1
To find more details about the REGEXP_LIKE please use the following link.
Related
I've got a query pulling data from a table. In one particular field, there are several cases where it is a zero, but I need the four digit location number. Here is where I'm running into a problem. I've got
SELECT REPLACE(locationNbr, '0', '1035') AS LOCATION...
Two issues -
Whoever put the table together made all fields VARCHAR, hence the single quotes.
In the cases where there already is the number 1035, I get 1103535 as the location number because it's replacing the zero in the middle of 1035.
How do I select the locationNbr field and leave it alone if it's anything other than zero (as a VARCHAR), but if it is zero, change it to 1035? Is there a way to somehow use TO_NUMBER within the REPLACE?
SELECT CASE WHEN locationNbr='0' THEN '1035' ELSE locationNbr END AS LOCATION...
REPLACE( string, string_to_replace , replacement_string )
REPLACE looks for a string_to_replace inside a string and replaces it with a replacent_string. That is why you get the undesired behaviour - you are using the wrong function.
CASE WHEN condition THEN result1 ELSE result2 END
CASE checks a condition and if it is true it returns result1 and if it is not it will return result2. This is a simple example, you can write a case statement with more than one condition check.
Don't use replace(). Use case:
(case when locationNbr = '0' then '1035' else locationNbr end)
You can make use of length in Oracle:
select case when length(loacation) = 1 then REPLACE(loacation, '0', '1035') else loacation end as location
from location_test;
I am trying to use a simple Translate function to replace "-" in a 23 digit string. The example of one such string is "1049477-1623095-2412303" The expected outcome of my query should be 104947716230952412303
The list of all "1049477-1623095-2412303" is present in a single column "table1". The name of the column is "data"
My query is
Select TRANSLATE(t.data, '-', '')
from table1 as t
However, it is returning 104947716230952000000 as the output.
At first, I thought it is an overflow error since the resulting integer is 20 digit so I also tried to use following
SELECT CAST(TRANSLATE(t.data,'-','') AS VARCHAR)
from table1 as t
but this is not working as well.
Please suggest a way so that I could have my desirable output
This is too long for a comment.
This code:
select translate('1049477-1623095-2412303', '-', '')
is going to return:
'104947716230952412303'
The return value is a string, not a number.
There is no way that it can return '104947716230952000000'. I could only imagine that happening if somehow the value is being converted to a numeric or bigint type.
Try regexp_replace()
Taking your own example, execute:
select regexp_replace('[string / column_name]','-');
It can be achieve RPAD try below code.
SELECT RPAD(TRANSLATE(CAST(t.data as VARCHAR),'-','') ,20,'00000000000000000000')
I have searched for and seen some similar questions, but none have solved my problem. I am getting a invalid number error on my TO_NUMBER in my where clause. Some things I have read said that it can be caused by where you place the TO_NUMBER in your where clause, so I was hoping someone could help me solve this. Here is the where clause in my query:
WHERE year_sec = TEST.YEAR_SEC_BY_DATE ('F', 0)
AND (year_sec = '2014F')
AND ((no_name LIKE '54%' AND user3 IS NOT NULL)
OR (SUBSTR (no_name, 1, 2) = '52' AND SUBSTR (no_name, 5, 1) = '8')
OR (no_name LIKE '56%'))
OR (TO_NUMBER(SUBSTR(year_sec,1,4), '9999') >= 2015)
AND ((no_name LIKE '543%' AND user3 IS NOT NULL)
OR (no_name LIKE '523%')
OR (no_name LIKE '563%'));
year_sec is always 4 digits with one letter after, and never null (if it isn't then there would be much bigger problems). So can anyone see why this would be causing the ORA-01722 error?
EDIT: Removed quotes, error while copying over sql.
Assuming that the error is coming from the to_number in your query and not, for example, from an invalid conversion in the year_sec_by_date function or somewhere else in your code, I would generally wager that Oracle is too dumb to lie to you. Somewhere in your data, you have at least one row where year_sec isn't a 4 digit number followed by a letter.
One way of finding the problem row would be to
CREATE OR REPLACE FUNCTION my_to_number( p_str IN VARCHAR2 )
RETURN NUMBER
IS
BEGIN
RETURN to_number( p_str );
EXCEPTION
WHEN others THEN
RETURN NULL;
END;
and then
SELECT year_sec, <<other columns>>
FROM <<your table>>
WHERE my_to_number( substr( year_sec, 1, 4 )) IS NULL
Note that if you have some rows where the year_sec is invalid that are being filtered out by other predicates in your query, there is no guarantee that Oracle will apply predicates in any particular order. Oracle may apply the to_number before or after any other predicate in the query.
The optimizer can rewrite your query and change where you expect the conversion to occur. Check for bad character data where you expect numeric data.
SELECT year_sec,
UPPER(SUBSTR(year_sec,1,4)) AS UPPER_YEAR,
LOWER(SUBSTR(year_sec,1,4)) AS LOWER_YEAR
FROM my_table
WHERE UPPER(SUBSTR(year_sec,1,4)) != LOWER(SUBSTR(year_sec,1,4))
From OraFAQ ORA-01722
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.
I need to search for and display a part of a string field. The string value from record to record may be different. For example:
Record #1
String Value:
IA_UnsafesclchOffense0IA_ReceivedEdServDuringExp0IA_SeriousBodilyInjuryN
Record #2
String Value:
IA_ReasonForRemovalTIA_Beh_Inc_Num1392137419IA_RemovalTypeNIA_UnsafesclchOffense0IA_ReceivedEdServDuringExp0IA_SeriousBodilyInjuryN
Record #3
String Value:
IA_UnsafesclchOffense0IA_RemovalTypeSIA_ReasonForRemovalPIA_ReceivedEdServDuringExp0IA_Beh_Inc_Num1396032888IA_SeriousBodilyInjuryN
In each case, I need to search for IA_Beh_Inc_Num. Assuming it's found, and IF it's followed by numeric data, I want to RETURN the numeric portion of that data. The numeric data, when present, will always be 10 characters.
In other words, record #1 should return no value, record #2 should return 1392137419 and record #3 should return 1396032888
Is there a way to do this within a select statement without having to write a full function with PL/SQL?
This should be easy with a Regular Expression: find a search string and check if it's followed by 10 digits:
REGEXP_SUBSTR(col, '(?<=IA_Beh_Inc_Num)([0-9]{10})')
but Oracle doesn't seem to support RegEx lookahead, so it's bit more complicated:
REGEXP_SUBSTR(value, '(IA_Beh_Inc_Num)([0-9]{10})',1,1,'i',2)
Remarks: the search is case-insensitive and if there are less than 10 digits NULL will be returned.
This would work:
SELECT
CASE WHEN instr(value, 'IA_Beh_Inc_Num') > 0
THEN substr(substr(value, instr(value, 'IA_Beh_Inc_Num'), 25),15,10)
ELSE 'not found'
END AS result
FROM example
See this SQL Fiddle.
Angelo's answer is correct for Oracle, as the question asked.
For those from SQL Server coming across this, the below would work:
SELECT CASE
WHEN CHARINDEX('IA_Beh_Inc_Num', StringColumn) = 0
THEN NULL
ELSE SUBSTRING(StringColumn, CHARINDEX('IA_Beh_Inc_Num', StringColumn) + LEN('IA_Beh_Inc_Num'), 10)
END AS unix_time
,*
FROM MyTable
EDIT:
Modified query to select all rows. The query prints "NOT A TIMESTAMP" if IA_Beh_Inc_Num does not exist within the string or if it is not followed by 10 numbers.
SELECT
DECODE
(
REGEXP_INSTR (value, 'IA_Beh_Inc_Num[0-9]{10}'),
0,
'NOT A TIMESTAMP',
SUBSTR(value, INSTR(value, 'IA_Beh_Inc_Num')+14, 10)
) timestamp
FROM example;
SQL Fiddle