15 September 2006

Deterministic Functions In Oracle

Oracle bulunan özelliklerden biri de deterministic fonksiyonlardır. Bir fonksiyonun deterministic olabilmesi için girilen bir değere karşı daima aynı sonucu üretmesidir. Sonucun sysdate e bağımlı bulunan bir fonksiyon deterministic değildir. Deterministic fonksiyonlar, function based index oluştururken gereklidirler. Aksi takdirde oluşturamazsınız. Deterministic fonksiyonların Oracle tarafında cache lendiği söylenmesine rağmen ben bunu gözlemleyemedim testlerimde. Aynı soruyu forums.oracle da sormama rağmen, oracle nin deterministik fonksiyonlar üzerinde nasıl bir yol izlediği konusunda net bir sonuca ulaşamadım.

Jonathan Lewis'in bu konuda yazmış olduğu bir makalede de bu durumdan bahsedilmiş. İsteyenler wiki sayfasına erişebilirler.

Aşağıda  James R Padfield in bu konuda yaptığı örnekte cache den söz edilebiliyor.

SQL> SET SERVEROUTPUT ON;
SQL> CREATE OR REPLACE FUNCTION format_deptno (
2 p_deptno IN VARCHAR2)
3 RETURN VARCHAR2
4 IS
5 BEGIN
6 DBMS_OUTPUT.PUT_LINE ('Department: ' || p_deptno);
7 RETURN 'Department: ' || p_deptno;
8 END;
9 /

Function created.

SQL> SELECT NULL
2 FROM emp
3 WHERE format_deptno (deptno) IS NULL;

no rows selected

SQL> EXEC NULL;
Department: 30
Department: 20
Department: 30
Department: 30
Department: 20
Department: 30
Department: 30
Department: 10
Department: 20
Department: 10
Department: 30
Department: 20
Department: 30
Department: 20
Department: 10

PL/SQL procedure successfully completed.

SQL> CREATE OR REPLACE FUNCTION format_deptno (
2 p_deptno IN VARCHAR2)
3 RETURN VARCHAR2 DETERMINISTIC
4 IS
5 BEGIN
6 DBMS_OUTPUT.PUT_LINE ('Department: ' || p_deptno);
7 RETURN 'Department: ' || p_deptno;
8 END;
9 /

Function created.

SQL> SELECT NULL
2 FROM emp
3 WHERE format_deptno (deptno) IS NULL;

no rows selected

SQL> EXEC NULL;
Department: 30
Department: 20
Department: 10

PL/SQL procedure successfully completed.

SQL>



Ama benim örneğimde bu cache i göremedim.
/*
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as HR
*/


CREATE OR REPLACE FUNCTION with_det_test(i IN NUMBER) RETURN NUMBER
DETERMINISTIC IS
BEGIN
dbms_output.put_line(i);
RETURN i;
END;


CREATE OR REPLACE FUNCTION without_det_test(i IN NUMBER) RETURN NUMBER IS
BEGIN
dbms_output.put_line(i);
RETURN i;
END;

DECLARE
a NUMBER;
i NUMBER := 1;
BEGIN
WHILE i < 10 LOOP
a := with_det_test( MOD(i, 2));
i := i + 1;
END LOOP;
END;
/*
1
0
1
0
1
0
1
0
1*/


DECLARE
a NUMBER;
i NUMBER := 1;
BEGIN
WHILE i < 10 LOOP
a := without_det_test(MOD(i, 2));
i := i + 1;
END LOOP;
END;
/*
1
0
1
0
1
0
1
0
1*/

No comments: