在Oracle 10g的SQL查询中,我需要确定字符串是否为数字。我怎么能这样做?
答案 0 :(得分:27)
您可以使用REGEXP_LIKE:
SELECT 1 FROM DUAL
WHERE REGEXP_LIKE('23.9', '^\d+(\.\d+)?$', '')
答案 1 :(得分:5)
你可以试试这个:
SELECT LENGTH(TRIM(TRANSLATE(string1, ' +-.0123456789', ' '))) FROM DUAL
其中string1是您正在评估的内容。如果是数字,它将返回null。请查看here以获得进一步说明
答案 2 :(得分:2)
我无法访问10G实例进行测试,但这适用于9i:
CREATE OR REPLACE FUNCTION is_numeric (p_val VARCHAR2) RETURN NUMBER IS v_val NUMBER; BEGIN BEGIN IF p_val IS NULL OR TRIM (p_val) = '' THEN RETURN 0; END IF; SELECT TO_NUMBER (p_val) INTO v_val FROM DUAL; RETURN 1; EXCEPTION WHEN OTHERS THEN RETURN 0; END; END; SELECT is_numeric ('333.5') is_numeric FROM DUAL;
我假设您希望将空值/空值视为FALSE。
答案 3 :(得分:2)
正如Tom Kyte在http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:7466996200346537833中所指出的,如果你在用户定义的函数中使用内置的TO_NUMBER
,你可能需要一些额外的技巧来使它工作。< / p>
FUNCTION is_number(x IN VARCHAR2)
RETURN NUMBER
IS
PROCEDURE check_number (y IN NUMBER)
IS
BEGIN
NULL;
END;
BEGIN
PRAGMA INLINE(check_number, 'No');
check_number(TO_NUMBER(x);
RETURN 1;
EXCEPTION
WHEN INVALID_NUMBER
THEN RETURN 0;
END is_number;
问题是优化编译器可以识别TO_NUMBER
的结果未在任何地方使用并优化它。
汤姆说(他的例子是关于日期而不是数字):
禁用函数内联将使其进行调用 check_date必须作为一个函数调用 - 使它成为一个函数调用 必须将DATE推送到调用堆栈。没有机会 在这种情况下,优化编译器以删除对to_date的调用。如果 调用check_date所需的to_date调用失败 原因,我们知道字符串输入在该日期不可转换 格式。
答案 4 :(得分:0)
这是一种确定数字的方法,可以在不创建函数的情况下成为简单查询的一部分。嵌入空格的帐户,+ - 不是第一个字符,或第二个小数点。
var v_test varchar2(20);
EXEC :v_test := ' -24.9 ';
select
(case when trim(:v_test) is null then 'N' ELSE -- only banks, or null
(case when instr(trim(:v_test),'+',2,1) > 0 then 'N' ELSE -- + sign not first char
(case when instr(trim(:v_test),'-',2,1) > 0 then 'N' ELSE -- - sign not first char
(case when instr(trim(:v_test),' ',1,1) > 0 then 'N' ELSE -- internal spaces
(case when instr(trim(:v_test),'.',1,2) > 0 then 'N' ELSE -- second decimal point
(case when LENGTH(TRIM(TRANSLATE(:v_test, ' +-.0123456789',' '))) is not null then 'N' ELSE -- only valid numeric charcters.
'Y'
END)END)END)END)END)END) as is_numeric
from dual;
答案 5 :(得分:-1)
我找到了解决方案
LENGTH(TRIM(TRANSLATE(string1, ' +-.0123456789', ' '))) is null
允许嵌入式空白......它接受&#34; 123 45 6789&#34;这对我来说不是一个数字。
另一级修剪/翻译纠正了这一点。以下将检测包含带有前导或尾随空白的连续数字的字符串字段,以便to_number(trim(string1))不会失败
LENGTH(TRIM(TRANSLATE(translate(trim(string1),' ','X'), '0123456789', ' '))) is null
答案 6 :(得分:-1)
对于整数,您可以使用以下内容。第一个转换将空格更改为字符,第二个转换将数字更改为空格。如果仅存在数字,则Trim将返回null。
TRIM(TRANSLATE(TRANSLATE(TRIM('1 2 3d 4'), ' ','@'),'0123456789',' ')) is null