Error on query with "Replace" - sql

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.

Related

ORA-01722: invalid number error

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.

ORACLE - TO_NUMBER Function

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.

Missing Keyword when trying to Select into

So I have a function to return an Average of a column such as
CREATE OR REPLACE FUNCTION avgCol
RETURN DEC IS avgNum DEC;
BEGIN
SELECT AVG(myCol)
INTO avgNum
FROM MyTable;
RETURN avgNum;
END;
/
While trying to test the results, i have the following
SELECT avgCol
INTO RESULT
FROM DUAL;
but it gives me the error
ORA-00905: missing keyword
00905. 00000 - "missing keyword"
*Cause:
*Action:
Error at Line: 175 Column: 6
Where line 175 is INTO RESULT. As far as I know, this is a scalar function and I'm trying to return a signal variable so it should work right? What keyword am I missing here?
Also I know I can just use AVG(), but I am learning how to create a scalar function. this is strictly for learning purposes.
While testing your code (which should be ok), you need
SELECT avgCol AS result FROM DUAL;
'INTO' assigns the result value to a PL/SQL variable; 'AS' creates an alias/name for a SQL SELECT (not PL/SQL) result column/field.

TO_NUMBER invalid number error

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

Assistance with SQL View

I'm having a little trouble with this sql view.
CREATE OR REPLACE VIEW view_themed_booking AS
SELECT tb.*,
CASE
WHEN (tb.themed_party_size % 2) = 0 THEN
(tb.themed_party_size-2)/2
ELSE ((tb.themed_party_size-2)/2) + 0.5
END themed_tables
FROM themed_booking tb;
Can anyone help me here? I'm trying to add a column to the end of the view that the natural number result of (S-2)/2 where S is the themed_party_size.
When i say natural number result i mean like round up the answers that end in .5 so if S=7 the answer would be 3 and not 2.5.
The error I get when I try and run the above code is
Error starting at line 1 in command:
CREATE OR REPLACE VIEW view_themed_booking AS
SELECT tb.*,
CASE WHEN (tb.themed_party_size % 2) = 0
THEN (tb.themed_party_size-2)/2
ELSE ((tb.themed_party_size-2)/2) + 0.5
END themed_tables
FROM themed_booking tb
Error at Command Line:3 Column:34
Error report:
SQL Error: ORA-00911: invalid character
00911. 00000 - "invalid character"
*Cause: identifiers may not start with any ASCII character other than
letters and numbers. $#_ are also allowed after the first
character. Identifiers enclosed by doublequotes may contain
any character other than a doublequote. Alternative quotes
(q'#...#') cannot use spaces, tabs, or carriage returns as
delimiters. For all other contexts, consult the SQL Language
Reference Manual.
*Action:
If it makes a difference I am using sqldeveloper connected to an oracle server so I can use PL/SQL.
The error message is telling you what the problem is.
Look at Line:3 Column:34
It is an invalid character
CREATE OR REPLACE VIEW view_themed_booking AS
SELECT tb.*,
CASE WHEN (tb.themed_party_size % 2) = 0
^
My suspicion is that you are trying to use the modulo operator.
Since you are using oracle PL/SQL, you should use mod
Here is a reference Oracle/PLSQL: Mod Function
I think you can simplify with the CEIL() or ROUND() function:
CREATE OR REPLACE VIEW view_themed_booking AS
SELECT tb.*,
ROUND((tb.themed_party_size-2)/2) AS themed_tables
FROM themed_booking tb;
Not sure why you get that error. Perhaps it's the % operator that is not available in Oracle. This links suggests so: Fundamentals of PL/SQL. There seems to be a MOD() function though.