我有一个包含此值的表格:
ID VALUE
-----------------------
23559 200
23562 -1 & {14376}#-1
我想做一个选择,如果我不能转换为数字设置NULL。
答案 0 :(得分:13)
我通常使用翻译,因为它是一个奇怪的角落案例:
SELECT
CASE
WHEN TRIM(TRANSLATE(COLUMN_NAME, '1234567890', ' ')) IS NULL THEN NULL
ELSE COLUMN_NAME
END AS "NUMERIC_COLUMN"
FROM
TABLE_NAME;
如果有必要,可以将其转变为程序,但我不确定在性能方面会有多少好处。
答案 1 :(得分:10)
您可以创建一个尝试将字符串转换为数字并捕获异常的函数。像
这样的东西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
答案 2 :(得分:8)
您也可以使用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 :(得分:2)
使用Oracle 12. 2 使用on conversion error
选项可以更轻松地完成此操作:
select id, cast(value as number default null on conversion error) as value
from the_table;
您也可以指定a format mask,类似于to_number()
功能。
我认为这比使用PL / SQL函数更快,与使用正则表达式的case
相比,不确定性能。但它肯定要短得多。
答案 4 :(得分:0)
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;