Por favor, considere o seguinte script:
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
*/
Posso confiar em f(x)
ser executado antes que o contexto seja lido dentro da visualização, como foi neste caso de teste executado na 10.2?
SELECT stuff FROM dbo.FuncReturningTable(param)
ou similar. O Oracle provavelmente tem funcionalidade equivalente. Embora, se você usar isso em grandes conjuntos de dados, tenha cuidado para monitorar o desempenho: não tenho certeza de quão brilhante o planejador de consultas precisaria para criar um plano eficiente a partir dessa sintaxe.Respostas:
Não.
Se você reescrever sua visualização com a filtragem de contexto na cláusula where (em vez da conexão por), obterá o valor definido anteriormente para o contexto:
Como a cláusula where é avaliada antes da seleção das colunas, o valor passado para a função não é definido até depois da leitura do contexto. O local da chamada sys_context na sua consulta (selecione onde, agrupar por etc.) afetará exatamente quando esse valor for definido.
fonte
De um modo geral, você não pode assumir com segurança nada sobre a ordem em que o DBMS fará as coisas ao avaliar uma única instrução SQL. É por isso que muitos DBMS não permitem que as funções usadas dessa maneira tenham efeitos colaterais (ou seja, o MSSQL não permite que as funções definam o estado global / de conexão que você está fazendo lá ou altere o conteúdo da tabela). Uma série de instruções deve ser executada de uma maneira que faça sentido de uma etapa para a seguinte (ou seja, elas são executadas em série ou da maneira que você não pode dizer que não foram), mas em uma única instrução o planejador de consultas tem domínio livre, desde que não introduza ambiguidade onde ainda não existe (no seu exemplo, ambiguidade já existe porque a função tem um efeito colateral afeta a exibição).
Se o planejador de consultas estivesse brilhante o suficiente para detectar que a exibição é afetada pelos efeitos colaterais da função, o que faria se você ingressasse em outra exibição que chamasse essa função potencialmente com diferentes valores de entrada? Ele pode ficar muito peludo rapidamente - esse tipo de coisa é porque geralmente, em qualquer contexto de programação, as funções não devem ter efeitos além de sua própria saída.
Neste exemplo específico, eu diria que é improvável que f (x) seja chamado primeiro, pois ele "exibe" parte da instrução: é provável que o conjunto de resultados da visualização seja recuperado antes de qualquer função dentro do lista de colunas a retornar são avaliadas. É claro que isso varia de acordo com o DBMS usado: eu não sou especialista em Oracle e os resultados de seus testes mostram que a função parece ser chamada primeiro nessas instâncias. Mas eu seria cauteloso em confiar na ordem de execução em qualquer instrução SQL da mesma forma - mesmo que sempre funcione da maneira que você espera no momento, pode não fazê-lo em futuras revisões (a menos que esteja oficialmente documentado em algum lugar em que a execução sempre será executada) desta maneira).
fonte
A documentação promete apenas que "o otimizador primeiro avalia expressões e condições contendo constantes o mais completamente possível". ( 10,2 , 11,2 ). Você não tem garantia de que ele avaliará primeiro qualquer expressão específica ou que não mudará essa ordem de tempos em tempos (um novo nível de patch na mesma versão?).
fonte