Oracle 10gのSQLクエリでは、文字列が数値かどうかを判断する必要があります。これどうやってするの?
REGEXP_LIKEを使用できます。
SELECT 1 FROM DUAL
WHERE REGEXP_LIKE('23.9', '^\d+(\.\d+)?$', '')
あなたはこれを試すことができます:
SELECT LENGTH(TRIM(TRANSLATE(string1, ' +-.0123456789', ' '))) FROM DUAL
ここで、string1は評価対象です。数値の場合はnullを返します。詳細については こちら を参照してください
テスト用の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として扱うことを望んでいると仮定しました。
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;
問題は、最適化コンパイラーmayがTO_NUMBER
はどこでも使用されておらず、最適化されます。
トムは言います(彼の例は数字ではなく日付についてでした):
関数のインライン化を無効にすると、check_dateの呼び出しが関数呼び出しとして行われ、DATEを呼び出しスタックにプッシュする必要があります。この場合、最適化コンパイラがto_dateの呼び出しを削除することはありません。 check_dateの呼び出しに必要なto_dateの呼び出しが何らかの理由で失敗した場合、文字列入力はその日付形式で変換できなかったことがわかります。
以下は、関数を作成せずに、単純なクエリの一部になる可能性がある数値を決定する方法です。埋め込まれたスペース、+-最初の文字ではない、または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;