CREATE TABLE log (created_on DATE)
Table created.
ALTER SESSION SET plsql_ccflags='use_determ:true'
Statement processed.
CREATE OR REPLACE PACKAGE getdata
IS
PROCEDURE log_count (title_in IN VARCHAR2);
FUNCTION n (i NUMBER)
RETURN NUMBER
$IF $$use_determ $THEN
DETERMINISTIC $END
;
FUNCTION vc (vc VARCHAR2)
RETURN VARCHAR2
$IF $$use_determ $THEN
DETERMINISTIC $END
;
FUNCTION b (b BOOLEAN)
RETURN BOOLEAN
$IF $$use_determ $THEN
DETERMINISTIC $END
;
END;
Package created.
CREATE OR REPLACE PACKAGE BODY getdata
IS
PROCEDURE log_count (title_in IN VARCHAR2)
IS
l_count PLS_INTEGER;
BEGIN
SELECT COUNT (*) INTO l_count FROM log;
DBMS_OUTPUT.put_line (title_in || '=' || l_count);
END;
PROCEDURE log_call
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO log
VALUES (SYSDATE);
COMMIT;
END;
FUNCTION n (i NUMBER)
RETURN NUMBER
$IF $$use_determ $THEN
DETERMINISTIC $END
IS
BEGIN
log_call ();
RETURN i;
END;
FUNCTION vc (vc VARCHAR2)
RETURN VARCHAR2
$IF $$use_determ $THEN
DETERMINISTIC $END
IS
BEGIN
log_call ();
RETURN vc;
END;
FUNCTION b (b BOOLEAN)
RETURN BOOLEAN
$IF $$use_determ $THEN
DETERMINISTIC $END
IS
BEGIN
log_call ();
RETURN b;
END;
END;
Package Body created.
CREATE OR REPLACE PROCEDURE tester (title_in IN VARCHAR2)
IS
n NUMBER;
vc VARCHAR2 (100);
b BOOLEAN;
BEGIN
DBMS_OUTPUT.put_line (title_in);
getdata.log_count ('N Before literal in loop');
FOR i IN 1 .. 10
LOOP
n := getdata.n (1);
/* Do something else inside the loop */
n := n + 1;
END LOOP;
getdata.log_count ('N After literal 10 iterations');
--
n := getdata.n (1);
n := getdata.n (1);
n := getdata.n (1);
n := getdata.n (1);
n := getdata.n (1);
n := getdata.n (1);
n := getdata.n (1);
n := getdata.n (1);
n := getdata.n (1);
n := getdata.n (1);
getdata.log_count ('N After literal 10 iterations outside loop');
--
FOR i IN 1 .. 10
LOOP
n := getdata.n (i / (i * 1));
END LOOP;
getdata.log_count ('N After expression 10 iterations');
--
FOR i IN 1 .. 10
LOOP
vc := getdata.vc ('abc');
END LOOP;
getdata.log_count ('VC After literal 10 iterations in loop');
--
vc := getdata.vc ('abc');
vc := getdata.vc ('abc');
vc := getdata.vc ('abc');
vc := getdata.vc ('abc');
vc := getdata.vc ('abc');
vc := getdata.vc ('abc');
vc := getdata.vc ('abc');
vc := getdata.vc ('abc');
vc := getdata.vc ('abc');
vc := getdata.vc ('abc');
getdata.log_count ('VC After literal 10 iterations outside loop');
--
FOR i IN 1 .. 10
LOOP
vc := getdata.vc ('abc' || TO_CHAR (1));
END LOOP;
getdata.log_count ('VC After expression 10 iterations');
--
FOR i IN 1 .. 10
LOOP
b := getdata.b (TRUE);
END LOOP;
getdata.log_count ('B After literal 10 iterations');
--
FOR i IN 1 .. 10
LOOP
b := getdata.b (CASE WHEN i < 100 THEN TRUE ELSE FALSE END);
END LOOP;
getdata.log_count ('B After expression 10 iterations');
END;
Procedure created.
BEGIN
tester ('Deterministic');
END;
Statement processed.
Deterministic
N Before literal in loop=0
N After literal 10 iterations=1
N After literal 10 iterations outside loop=11
N After expression 10 iterations=21
VC After literal 10 iterations in loop=22
VC After literal 10 iterations outside loop=32
VC After expression 10 iterations=42
B After literal 10 iterations=43
B After expression 10 iterations=53
ALTER SESSION SET plsql_ccflags='use_determ:false'
Statement processed.
ALTER PACKAGE getdata COMPILE
Package altered.
ALTER PACKAGE getdata COMPILE BODY
Package altered.
BEGIN
DELETE FROM log;
tester ('Non-deterministic');
END;
Statement processed.
Non-deterministic
N Before literal in loop=0
N After literal 10 iterations=10
N After literal 10 iterations outside loop=20
N After expression 10 iterations=30
VC After literal 10 iterations in loop=40
VC After literal 10 iterations outside loop=50
VC After expression 10 iterations=60
B After literal 10 iterations=70
B After expression 10 iterations=80