web-dev-qa-db-ja.com

SQLで文字列が数値であるかどうかをどのように判断できますか?

Oracle 10gのSQLクエリでは、文字列が数値かどうかを判断する必要があります。これどうやってするの?

13
AndyGeek

REGEXP_LIKEを使用できます。

SELECT 1 FROM DUAL
WHERE REGEXP_LIKE('23.9', '^\d+(\.\d+)?$', '') 
27
Chandu

あなたはこれを試すことができます:

SELECT LENGTH(TRIM(TRANSLATE(string1, ' +-.0123456789', ' '))) FROM DUAL

ここで、string1は評価対象です。数値の場合はnullを返します。詳細については こちら を参照してください

5

テスト用の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; [。 ____。 END; 
 
 
 SELECT is_numeric( '333.5')is_numeric 
 FROM DUAL; 
 

私はあなたがヌル/空をFALSEとして扱うことを望んでいると仮定しました。

2
Evan Haas

http://asktom.Oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:74669962003465378 を使用している場合、Tom Kyteが指摘したように組み込みTO_NUMBERユーザー定義関数では、機能させるために少し工夫が必要になる場合があります。

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;

問題は、最適化コンパイラーmayTO_NUMBERはどこでも使用されておらず、最適化されます。

トムは言います(彼の例は数字ではなく日付についてでした):

関数のインライン化を無効にすると、check_dateの呼び出しが関数呼び出しとして行われ、DATEを呼び出しスタックにプッシュする必要があります。この場合、最適化コンパイラがto_dateの呼び出しを削除することはありません。 check_dateの呼び出しに必要なto_dateの呼び出しが何らかの理由で失敗した場合、文字列入力はその日付形式で変換できなかったことがわかります。

2
SQB

以下は、関数を作成せずに、単純なクエリの一部になる可能性がある数値を決定する方法です。埋め込まれたスペース、+-最初の文字ではない、または2番目の小数点を考慮します。

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;
0
John Ryan