SQL: если не может преобразовать to_number, установленный как ноль - PullRequest
8 голосов
/ 24 июня 2011

У меня есть таблица с такими значениями:

ID      VALUE
-----------------------
23559   200
23562   -1 & {14376}#-1

и я хочу сделать выбор, который, если я не могу преобразовать в число, установлено в NULL.

Ответы [ 5 ]

13 голосов
/ 24 июня 2011

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

SELECT 
  CASE
     WHEN TRIM(TRANSLATE(COLUMN_NAME, '1234567890', ' ')) IS NULL THEN NULL
     ELSE COLUMN_NAME
  END AS "NUMERIC_COLUMN"
FROM
  TABLE_NAME;

При необходимости это можно превратить в процедуру, но я не уверен, что будет очень многоулучшение производительности.

10 голосов
/ 24 июня 2011

Вы можете создать функцию, которая пытается преобразовать строку в число и перехватывает исключение.Что-то вроде

CREATE OR REPLACE FUNCTION my_to_number( p_str IN VARCHAR2 )
  RETURN NUMBER
IS
  l_num NUMBER;
BEGIN
  BEGIN
    l_num := to_number( p_str );
  EXCEPTION
    WHEN others THEN
      l_num := null;
  END;

  RETURN l_num;
END;

Тогда вы можете

SELECT id, my_to_number( value )
  FROM your_table
8 голосов
/ 24 июня 2011

Вы также можете использовать REGEXP_LIKE:

SELECT id
     , CASE WHEN regexp_like(value,'^[0-9]+$') THEN TO_NUMBER(value)
            ELSE NULL
        END value
  FROM your_table;

Например:

SQL> WITH q AS (
  2  SELECT 1 ID, '200' col FROM dual
  3  UNION
  4  SELECT 2, '-1 & {14376}#-1' FROM dual
  5  )
  6  SELECT id, CASE WHEN regexp_like(col,'^[0-9]+$') THEN TO_NUMBER(col) ELSE NULL END TEST FROM q;

        ID       TEST
---------- ----------
         1        200
         2 
3 голосов
/ 27 октября 2017

С Oracle 12. 2 это можно сделать немного проще, используя опцию on conversion error:

select id, cast(value as number default null on conversion error) as value
from the_table;

При желании вы также можете указать маску формата , аналогично функции to_number().

Я предполагаю, что это будет быстрее, чем использование функции PL / SQL, но я не уверен в производительности по сравнению с case с регулярным выражением. Но это определенно намного короче.

0 голосов
/ 24 июня 2011
CREATE OR REPLACE FUNCTION asnumber(p_val IN VARCHAR2) RETURN NUMBER IS
l_val NUMBER;
BEGIN
   l_val := TO_NUMBER(p_val);
   RETURN l_val;
EXCEPTION WHEN VALUE_ERROR THEN
   RETURN null;
END;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...