如何在Oracle 9i中知道哪些值是数值型的

3

我有一个包含varchar类型的数据库。

我想知道哪些记录保存了数字值。我尝试了REGEXP_COUNT和其他方法,但我的数据库版本是9i,我认为这些方法是针对10g及以上版本的。

我该如何实现这个功能?

我已经尝试过:

 select to_number( my_column ) from my_table 

但是它不起作用,因为并非所有的员工ID都是数字。

编辑

背景。

这个表格包含员工ID,所有的员工ID都是数字(如1234、24523或6655)。

在初始数据库加载时,当员工ID未知时,他们使用了文本而不是像-1这样的内容:

NA, N/A, NONE, UNK, UNKNOW, TEST, EXTERNAL, WITHOUT_ID

实际上,主要问题在于该列应该是数字,而不是varchar

现在,我试图获取所有不是数字的记录(不包含员工ID),但由于该数据库是9i版本,无法使用RegExp。


注意事项:9i、转换和SQL是与此相关的标签。 - OscarRyz
8个回答

4

很抱歉,您需要编写自己的isnumber函数,并使用它,类似于这样(未经测试)在这个线程中找到的代码,应该可以工作。

 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;

之后,您可以使用解码函数与您的isnumber函数结合使用,以获得所需的结果。

2
不错,但如果要在SQL中使用该函数,则不能返回BOOLEAN - 将其更改为返回NUMBER(0/1)或VARCHAR2(Y / N)。 - Tony Andrews
确实作为数字要好得多 :) - pedromarce
1
给代码点个赞,但是我很想踩一下那个需要注册才能查看内容的网站的参考链接 :-| 最好引用asktom:http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:15321803936685 - DCookie

3

又一个纯SQL解决方法:

select my_column
  from my_table
 where translate(my_column,'x0123456789','x') is null;

1
这仅适用于整数。但在您匆忙将小数点添加到TRANSLATE()列表之前,请记住IP地址不是数字,因此123.456.789.255必须未通过测试。 - APC
当然,这就是为什么有“workaround(变通方法)”。但有时它可以帮助并且很简单。 - Egor Rogov

1

这取决于你认为什么是“数字”。你允许负数、小数或只允许整数,还是科学计数法(例如“1e3”)?前导零是否允许?

如果你只想要正整数值,请尝试

where translate(col,' 1234567890','0') is null

1

试试这个

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;
/

在这上面运行它...

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
       )

返回

MY_COLUMN     MY_COLUMN_NUM
------------- -------------
mydoghas3legs
27.5                   27.5
27.50.5

1

我不喜欢在正常代码中使用异常,但这似乎是最好和最安全的方法:

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;

0
这是我编写的程序版本,类似于pedromarce发布的版本。请注意,由于“-”异常数字,所发布的示例无法编译。此示例可以编译并正常运行:
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;

使用示例:

select IsNumber('zzz') from dual;

结果:N

select IsNumber('123.45') from dual;

结果:Y


0
我成功地绕过了这个问题,方法如下:
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%' 

有点脏,但是能用。;)


如果此查询试图获取不包含数字的行,则如果该值中某处有数字,则会失败,请尝试使用“mydoghas3legs”。 - PaulJ
啊,不好意思,实际上我试图获取所有非数字值。...我会更新我的原始问题。 - OscarRyz

0

另一种方法,这里是我之前写的一个函数:

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;
/

正如pedromarce的回答所指出的那样,您可能需要将其从布尔返回更改为数字或varchar2以更好地满足您的需求。

2
另一个无法处理小数点的程序。另外,这个程序的性能可能非常差。 - APC
将小数点添加到函数中非常简单,不需要评论。我从未声称这个函数是完美的,但它适合我的需求,也可能适用于OP。如果经常调用此函数和/或处理非常大的字符串,则性能才会成为一个重要问题。 - AndyDan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接