Merhabalar,
Hemen hemen tüm uygulamalarda ve senaryolarda kullanmak
durumunda olduğumuz “bir string numeric mi değil mi?” methodu için Steven
Feuerstein PL/SQL Programming kitabında şöyle bir yöntemi tarif eder:
CREATE OR REPLACE FUNCTION is_numeric (p_value VARCHAR2)
RETURN BOOLEAN IS
v_test_number NUMBER;
BEGIN
v_test_number :=
to_number(p_value);
RETURN TRUE;
EXCEPTION
WHEN value_error THEN
RETURN FALSE;
END is_numeric;
Yani string numeric değilse to_number conversion sırasında
value_error exception’a düşecek ve false değer dönecek, diğer türlü true
diyecek ve işlem doğru biçimde tamamlanacak.
Bir sistem için optimizasyon çalışmaları yürütüyordum ve aklıma daha süratli bir yöntem olup olamayacağı geldi. Bunun için 11g de tanıtılan regular
expression yönteminin doğru olabileceğini düşünüp aşağıdaki gibi bir program
yazdım:
CREATE OR REPLACE FUNCTION is_numeric(i_value IN VARCHAR2)
RETURN BOOLEAN IS
BEGIN
RETURN length(i_value) =
regexp_count(i_value, '[[:digit:]]');
END is_numeric;
Regexp_count gelen string içerisindeki digit sayısını arıyor
ve gelen stringin uzunluğu ile aynı ise numeric oluyor, diğer türlü false
değeri dönüyor. Buradaki kritik soru hangisi daha performanslı (zaten amaç ta
buydu). Ben performans testlerini yapabilmek için program isimlerini
is_numeric_exceptive (ilk örnek) ve is_numeric_regexp (ikinci örnek) olarak
değiştirdim.
Sonuç:
Regular Expression: 74
Exceptive: 84
DECLARE
l_result BOOLEAN;
l_start PLS_INTEGER;
l_end PLS_INTEGER;
BEGIN
l_start :=
dbms_utility.get_cpu_time;
FOR i IN 1 .. 100000 LOOP
l_result :=
is_numeric_regexp(dbms_random.string('X', 5));
END LOOP;
l_end :=
dbms_utility.get_cpu_time;
dbms_output.put_line('Regular
Expression: ' ||
to_char(l_end - l_start));
------------------------------------------------------
l_start :=
dbms_utility.get_cpu_time;
FOR i IN 1 .. 100000 LOOP
l_result :=
is_numeric_exceptive(dbms_random.string('X', 5));
END LOOP;
l_end :=
dbms_utility.get_cpu_time;
dbms_output.put_line('Exceptive: ' || to_char(l_end
- l_start));
END;
Hiç yorum yok:
Yorum Gönder