如何确定SQL中的字符串是否为数字?

时间:2011-04-14 17:13:06

标签: sql oracle10g numeric

在Oracle 10g的SQL查询中,我需要确定字符串是否为数字。我怎么能这样做?

7 个答案:

答案 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