Пожалуйста, рассмотрите следующий скрипт:
create or replace function f(p_limit in integer) return integer as
begin
set_global_context ('limit', p_limit);
return p_limit;
end;
/
create view v as
select level as val from dual connect by level<=sys_context('global_context','limit');
select f(2), v.* from v;
/*
F(2) VAL
---------------------- ----------------------
2 1
2 2
*/
select f(4), v.* from v;
/*
F(4) VAL
---------------------- ----------------------
4 1
4 2
4 3
4 4
*/
Могу ли я рассчитывать на f(x)
выполнение до того, как контекст будет прочитан внутри представления, как это было в этом тестовом примере на 10.2?
SELECT stuff FROM dbo.FuncReturningTable(param)
или подобное. Oracle, вероятно, имеет эквивалентную функциональность. Хотя, используя это для больших наборов данных, я бы внимательно следил за производительностью: я не уверен, насколько ярким должен быть планировщик запросов, чтобы составить эффективный план с таким синтаксисом.Ответы:
Нет.
Если вы переписываете свое представление с фильтрацией контекста по предложению where (вместо connect by), вы получите предварительно установленное значение для контекста:
Поскольку предложение where оценивается до выбора столбцов, значение, переданное функции, не устанавливается до тех пор, пока не будет прочитан контекст. Расположение вызова sys_context в вашем запросе (выберите, где, сгруппировать и т. Д.) Повлияет именно на это значение.
источник
Вообще говоря, вы не можете с уверенностью предположить что-либо о порядке, в котором ваша СУБД будет действовать при оценке одного оператора SQL. Вот почему многие СУБД не позволяют таким функциям иметь побочные эффекты (т. Е. MSSQL не позволяет функциям устанавливать глобальное состояние / состояние соединения, которое вы там делаете, или изменять содержимое таблицы). Последовательность операторов должна выполняться так, чтобы иметь смысл от одного шага к следующему (то есть они выполняются последовательно или таким образом, что вы не можете сказать, что это не так), но внутри одного оператора планировщик запросов имеет свободное правление до тех пор, пока оно не вводит неоднозначность там, где ее еще нет (в вашем примере неоднозначность уже существует, поскольку функция имеет побочный эффект, влияющий на представление).
Если планировщик запросов был достаточно ярким, чтобы обнаружить, что на представление влияют побочные эффекты функции, что бы он сделал, если бы вы присоединились к другому представлению, которое потенциально вызывало эту функцию с другими входными значениями? Это может очень быстро стать очень пугающим - такого рода вещи, поэтому, как правило, в любом контексте программирования функции не должны иметь эффектов, выходящих за пределы их собственного вывода.
В этом конкретном примере я бы сказал, что маловероятно, что f (x) будет вызван первым, поскольку он «отображает» часть оператора: результирующий набор из представления, вероятно, будет получен до каких-либо функций внутри список возвращаемых столбцов оценивается. Конечно, это будет зависеть от используемой СУБД: я не эксперт Oracle, и результаты ваших тестов показывают, что в этих случаях эта функция вызывается первой. Но я бы все же опасался полагаться на порядок выполнения в любом отдельном операторе SQL - даже если он всегда работает так, как вы ожидаете сейчас, это может не сработать в будущих ревизиях (если только где-то не будет официально задокументировано, что выполнение всегда будет идти так наоборот).
источник
Документация только обещает, что «оптимизатор сначала оценивает выражения и условия, содержащие константы, как можно полнее». ( 10.2 , 11.2 ). Вам не гарантируется, что он сначала оценит какое-либо конкретное выражение или что он не будет время от времени изменять этот порядок (новый уровень исправлений в том же выпуске?).
источник