あなたが尋ねた実際の質問については、@Daveが正しいのですが、達成しようとしていることは、あなたがやっていることとは異なると思います。書かれているように、PL/SQLブロックは値が最初の非番号になるまで評価します。あなたはすべての値が評価されたい場合は、このようなものが必要です:ループ内に例外処理を移動させることで
BEGIN
FOR rec IN (SELECT '10' house_nr FROM DUAL
UNION ALL
SELECT '10a' house_nr FROM DUAL
UNION ALL
SELECT '11' house_nr FROM DUAL) LOOP
error_fl := FALSE;
BEGIN
number_correct := TO_NUMBER(rec.house_nr);
EXCEPTION
WHEN VALUE_ERROR THEN
error_fl := TRUE;
WHEN OTHERS THEN
RAISE;
END;
IF error_fl THEN
DBMS_OUTPUT.put_line('incorrect: ' || rec.house_nr);
ELSE
DBMS_OUTPUT.put_line('correct: ' || rec.house_nr);
END IF;
END LOOP;
END;
をエラーが発生した後、我々は処理を継続することができます。また、このバージョンでは、予期しないエラーではなく、実際に発生したエラーが変換エラーである場合にのみ、「間違った」メッセージが返されます。このような特定の条件に対してエラー処理を記述するときは、できるだけ正確にすることが重要です。
@Stephenが指摘するように、正規表現は、一般に、PL/SQLプロシージャまたは関数よりも高速であり、単一のSQLステートメントは、典型的には、手続きのループよりも優れています。しかし、正規表現の機能はwhere
句でのみ使用することができますので、あなたはすべての値の結果を確認したい場合は、二回あなたのテーブルを照会する必要があるだろう:
WITH test_num as (SELECT '10' house_nr FROM DUAL
UNION ALL
SELECT '10a' house_nr FROM DUAL
UNION ALL
SELECT '11' house_nr FROM DUAL)
SELECT 'correct' AS status, a.*
FROM test_num a
WHERE REGEXP_LIKE(t1, '[^[:digit:]]')
UNION ALL
SELECT 'incorrect', a.*
FROM test_num a
WHERE NOT REGEXP_LIKE(t1, '[^[:digit:]]');
あなたが正規表現に慣れていない場合、またはこれは、ほとんどの状況で正規表現を使用したほど速くはありません
CREATE OR REPLACE FUNCTION is_num(p_string VARCHAR2)
RETURN NUMBER
DETERMINISTIC IS
v_test NUMBER;
BEGIN
v_test := p_string;
RETURN 1;
EXCEPTION
WHEN VALUE_ERROR THEN
RETURN 0;
WHEN OTHERS THEN
RAISE;
END;
WITH test_num as (SELECT '10' house_nr FROM DUAL
UNION ALL
SELECT '10a' house_nr FROM DUAL
UNION ALL
SELECT '11' house_nr FROM DUAL)
SELECT CASE is_num(t1) WHEN 0 THEN 'correct' ELSE 'incorrect' END AS status, a.*
FROM test_num a;
、しかし:あなたはまだ独自の関数を作成することによって、単一のSQL文でこれを行うことができ、適当な発現を思い付くことができません関数ベースのインデックスはregexp関数については細心の注意を払っていますが、このような関数には問題はありません。この特定のクエリのインデックスが必要なようには思えませんが、それは何かを覚えておいてください。
あなたは正しいです。私はすべての価値を評価したい。 – reforrer