3

我有这个包含 varchar 的数据库。

我想知道哪些记录包含数值。我试过REGEXP_COUNT了,但我在 9i 上运行,我认为这是 10g >

我怎样才能做到这一点?

我试过了:

 select to_number( my_column ) from my_table 

但这不起作用,因为并非所有这些都是数字的。

编辑

背景。

此表包含员工 ID,所有这些都是数字(读取 1234 或 24523 或 6655)

在初始数据库加载中,当员工 id 未知而不是使用类似-1他们输入的文本时,例如:

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

真正的主要错误是,该列是varchar而不是应有的数字。

现在,我尝试做的是获取所有非数字记录(不包含员工 id),但由于 db 是 9i,我无法使用 RegExp

4

8 回答 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;

之后,您可以使用 decode 函数结合您的 isnumber 函数来获得您需要的结果。

于 2009-11-12T17:32:59.603 回答
3

只是另一个纯 SQL 解决方法:

select my_column
  from my_table
 where translate(my_column,'x0123456789','x') is null;
于 2009-11-12T18:56:10.577 回答
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;
于 2009-11-13T14:50:57.787 回答
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
于 2009-11-13T09:22:11.473 回答
1

取决于您将什么视为“数字”。您是否允许负数、小数或仅整数或科学记数法(例如'1e3')。是否允许前导零?

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

where translate(col,' 1234567890','0') is null
于 2009-11-12T22:01:17.427 回答
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%' 

很脏,但它有效。;)

于 2009-11-12T17:56:32.803 回答
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 的回答所指出的,您可能需要将其从布尔返回更改为 number 或 varchar2 以更好地满足您的需求。

于 2009-11-12T22:54:43.387 回答
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;

结果:是

于 2011-07-08T23:07:55.447 回答