How can I know which values are numeric in oracle 9i

旧时模样 提交于 2020-01-04 03:59:07

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!