Это такая ситуация, когда некоторые эксперименты полезны (это было проведено на 10g). Используя следующий запрос, мы можем сказать, что обычные функции, использующие одни и те же параметры (в данном случае ни одного), будут выполняться при каждом вызове:
select dbms_random.value() from all_tables
Это связано с тем, что Oracle предполагает, что функция не будет возвращать одно и то же значение последовательно, если вы не укажете обратное. Мы можем сделать это, создав функцию с помощью ключевого слова deterministic
:
CREATE FUNCTION rand_det
RETURN NUMBER
DETERMINISTIC AS
BEGIN
RETURN DBMS_RANDOM.VALUE ();
END;
Использование этой функции вместо dbms_random
в первом запросе говорит нам, что запрос выполняется только один раз, несмотря на множество вызовов. Но это только проясняет раздел select
. Что, если мы используем одну и ту же детерминированную функцию в выражении select
и where
. Мы можем проверить это, используя следующий запрос:
SELECT rand_det
FROM all_tables
WHERE rand_det > .5;
Возможно, вам придется выполнить это несколько раз, чтобы увидеть наше доказательство, но, в конце концов, вы увидите список значений менее 0,5. Это дает нам свидетельство того, что даже детерминированная функция выполняется дважды: один раз для каждого раздела, в котором она появляется. В качестве альтернативы вы можете изменить нашу детерминированную функцию следующим образом, а затем выполнить следующий запрос, который покажет 2 строки, записанные в DBMS_OUTPUT
.
CREATE OR REPLACE FUNCTION rand_det
RETURN NUMBER
DETERMINISTIC AS
BEGIN
DBMS_OUTPUT.put_line ('Called!');
RETURN DBMS_RANDOM.VALUE ();
END;
SELECT rand_det
FROM all_tables;