Как я могу узнать, какие значения являются числовыми в Oracle 9i - PullRequest
3 голосов
/ 12 ноября 2009

У меня есть база данных, которая содержит varchar.

Я хочу знать, какие записи содержат числовые значения. Я пробовал REGEXP_COUNT и другие, но я работаю на 9i, и я думаю, что это для 10g>

Как мне этого добиться?

Я пытался:

 select to_number( my_column ) from my_table 

Но это не работает, потому что не все они числовые.

EDIT

Фоновая.

Эта таблица содержит идентификаторы сотрудников, все из которых являются числовыми (читать 1234 или 24523 или 6655)

В начальной загрузке базы данных, когда идентификатор сотрудника был неизвестен, вместо того, чтобы использовать что-то вроде -1, они вводили такие тексты, как:

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

На самом деле главная ошибка в том, что столбец varchar, а не номер, как должно.

Теперь, что я пытаюсь сделать, это получить все записи, которые не являются числовыми (которые не содержат идентификатора сотрудника), но, поскольку эта база данных равна 9i, я не смог использовать RegExp

Ответы [ 8 ]

4 голосов
/ 12 ноября 2009

Боюсь, вам придется написать свою собственную функцию 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 для получения нужных вам результатов.

3 голосов
/ 12 ноября 2009

Просто еще один обходной путь чистого SQL:

select my_column
  from my_table
 where translate(my_column,'x0123456789','x') is null;
1 голос
/ 13 ноября 2009

Мне не нравится использовать исключения в обычном коде, но это, кажется, лучший и самый безопасный подход:

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;
1 голос
/ 13 ноября 2009

Попробуйте это

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 голос
/ 13 ноября 2009

Зависит от того, что вы считаете «числовым». Вы допускаете отрицательные числа, десятичные числа или просто целые числа, или научную запись (например, «1e3») Разрешены ли ведущие нули?

Если вам нужны только положительные целые значения, попробуйте

where translate(col,' 1234567890','0') is null
0 голосов
/ 09 июля 2011

Вот моя версия рутины, похожая на ту, которую опубликовал 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 голосов
/ 13 ноября 2009

Еще один подход, вот функция, которую я написал некоторое время назад:

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

Как указано в ответе Педромарса, вам, возможно, придется изменить его с логического возврата на число или varchar2, чтобы лучше соответствовать вашим потребностям.

0 голосов
/ 12 ноября 2009

Мне удается обойти вот так:

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%' 

Грязно, но работает. ;)

...