问题
I have this database which contains a varchar.
I want to know which records holds numeric values. I tried REGEXP_COUNT
and other but I'm running on 9i and I think this is for 10g >
How can I achieve this?
I tried:
select to_number( my_column ) from my_table
But it doesn't work, because well not all of them are numeric.
EDIT
Background.
This table contains employee id's, all of which are numeric ( read 1234 or 24523 or 6655 )
The in the initial database load, when the employee id was unknown instead of using something like -1
they entered texts like:
NA, N/A, NONE, UNK, UNKNOW, TEST, EXTERNAL, WITHOUT_ID
Really the main fault is, that column is varchar
and not number as it should.
Now, what I try to do, is to get ll the records that are not numeric ( that don't contain an employee id ) but since that db is 9i, I could not use RegExp
回答1:
I am afraid you'll have to write your own isnumber function, and then use it, something like this (untested) found in this thread, should work.
DECLARE FUNCTION isNumber(p_text IN VARCHAR2) RETURN NUMBER IS
v_dummy NUMBER;
not_number EXCEPTION;
PRAGMA EXCEPTION_INIT(-, not_number);
BEGIN
v_dummy := TO_NUMBER(p_text);
RETURN 1;
EXCEPTION
WHEN not_number THEN RETURN 0;
END is_number;
After that you could use a decode function combined with your isnumber function to get the results you need.
回答2:
Just another pure SQL workaround:
select my_column
from my_table
where translate(my_column,'x0123456789','x') is null;
回答3:
Depends on what you count as 'numeric'. Do you allow negative numbers, decimals or just integers, or scientific notation (eg '1e3'). Are leading zeroes allowed ?
If you just want positive integer values, try
where translate(col,' 1234567890','0') is null
回答4:
Try this
CREATE OR REPLACE PACKAGE value_tests
AS
FUNCTION get_number( pv_value IN VARCHAR2 ) RETURN NUMBER;
END;
/
CREATE OR REPLACE PACKAGE BODY value_tests
AS
FUNCTION get_number( pv_value IN VARCHAR2 ) RETURN NUMBER
IS
converted_number NUMBER;
invalid_number EXCEPTION;
PRAGMA EXCEPTION_INIT( invalid_number, -01722 );
value_error EXCEPTION;
PRAGMA EXCEPTION_INIT( value_error, -06502 );
BEGIN
<<try_conversion>>
BEGIN
converted_number := TO_NUMBER( pv_value );
EXCEPTION
WHEN invalid_number OR value_error
THEN
converted_number := NULL;
END try_conversion;
RETURN converted_number;
END get_number;
END;
/
Running it on this...
select my_column
, value_tests.get_number( my_column ) my_column_num
from ( select 'mydoghas3legs' my_column from dual
union all select '27.5' my_column from dual
union all select '27.50.5' my_column from dual
)
returns
MY_COLUMN MY_COLUMN_NUM
------------- -------------
mydoghas3legs
27.5 27.5
27.50.5
回答5:
I do not like using exceptions in normal code but this seems to be the best and safest aproach:
CREATE OR REPLACE FUNCTION "IS_NUMBER" (pX in varchar2) return integer is
n number;
begin
n:=to_number(pX);
return 1;
exception
when others then
return 0;
end;
回答6:
I manage to work around like this:
select my_column
from my_table
where my_column not like '%1%'
and my_column not like '%2%'
and my_column not like '%3%'
and my_column not like '%4%'
and my_column not like '%5%'
and my_column not like '%6%'
and my_column not like '%7%'
and my_column not like '%8%'
and my_column not like '%9%'
and my_column not like '%0%'
Dirty, but it works. ;)
回答7:
Yet another approach, here's a function I wrote some time ago:
CREATE OR REPLACE function string_is_numeric
(p_string_in in varchar2)
return boolean is
begin
for i in 1..length(p_string_in) loop
if substr(p_string_in, i, 1) not in ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') then
return false;
end if;
end loop;
return true;
end;
/
As pointed out in pedromarce's answer, you might need to change that from a boolean return to number or varchar2 to better suit your needs.
回答8:
Here's my version of the routine, similar to that posted by pedromarce. Note that the posted example doesn't compile due to the "-" exception number. This example compiles and works:
create or replace function IsNumber(
a_Text varchar2
) return char is
t_Test number;
begin
begin
t_Test := to_number(a_Text);
return 'Y';
exception when value_error then
return 'N';
end;
end;
Example usage:
select IsNumber('zzz') from dual;
Result: N
select IsNumber('123.45') from dual;
Result: Y
来源:https://stackoverflow.com/questions/1723925/how-can-i-know-which-values-are-numeric-in-oracle-9i