A avaliação de curto-circuito CASE e COALESCE funciona com sequências em PL / SQL, mas não em SQL
A avaliação de curto-circuito descrita na documentação paraCASE
eCOALESCE()
aplicar a seqüências quando usado no SQL? Isso não parece estar acontecendo.
O oraculodocumentação sobreCASE
afirma que:
O banco de dados Oracle usa avaliação de curto-circuito. Por um simplesCASE
expressão ... O Oracle nunca avalia uma comparação_expr se uma comparação_expr anterior for igual a expr. Para uma expressão CASE pesquisada, o banco de dados ... nunca avalia uma condição se a condição anterior for verdadeira.
Da mesma forma paraCOALESCE()
a documentação afirma que:
O banco de dados Oracle usa avaliação de curto-circuito. O banco de dados avalia cada valor expr e determina se é NULL, em vez de avaliar todos os valores expr antes de determinar se algum deles é NULL.
Ao chamar uma sequência do SQL, isso não parece ser o caso; como você pode ver, nenhum curto-circuito ocorre e a sequência é incrementada.
SQL> create sequence tmp_test_seq start with 1 increment by 1;
SQL> select tmp_test_seq.nextval from dual;
NEXTVAL
----------
1
SQL> select tmp_test_seq.currval from dual;
CURRVAL
----------
1
SQL> select coalesce(1, tmp_test_seq.nextval) from dual;
COALESCE(1,TMP_TEST_SEQ.NEXTVAL)
--------------------------------
1
SQL> select tmp_test_seq.currval from dual;
CURRVAL
----------
2
SQL> select case when 1 = 1 then 1 else tmp_test_seq.nextval end as s from dual;
S
----------
1
SQL> select tmp_test_seq.currval from dual;
CURRVAL
----------
3
Entretanto, ao chamar do PL / SQL, a sequência énão incrementado:
SQL> create sequence tmp_test_seq start with 1 increment by 1;
SQL> declare
2 i number;
3 begin
4 i := tmp_test_seq.nextval;
5 dbms_output.put_line(tmp_test_seq.currval);
6 i := coalesce(1, tmp_test_seq.nextval);
7 dbms_output.put_line(i);
8 dbms_output.put_line(tmp_test_seq.currval);
9 i := case when 1 = 1 then 1 else tmp_test_seq.nextval end;
10 dbms_output.put_line(i);
11 dbms_output.put_line(tmp_test_seq.currval);
12 end;
13 /
1
1
1
1
1
SQL> select tmp_test_seq.nextval from dual;
NEXTVAL
----------
2
Chamar a sequência no SQL de PL / SQL com os mesmos resultados que com o SQL:
SQL> create sequence tmp_test_seq start with 1 increment by 1;
SQL> declare
2 i number;
3 begin
4 select tmp_test_seq.nextval into i from dual;
5 dbms_output.put_line(tmp_test_seq.currval);
6 select coalesce(1, tmp_test_seq.nextval) into i from dual;
7 dbms_output.put_line(i);
8 dbms_output.put_line(tmp_test_seq.currval);
9 select case when 1 = 1 then 1 else tmp_test_seq.nextval end into i
10 from dual;
11 dbms_output.put_line(i);
12 dbms_output.put_line(tmp_test_seq.currval);
13 end;
14 /
1
1
2
1
3
Parece não haver nada na documentação sobre isso;o guia do administrador para gerenciar sequências, a referência da linguagem SQL na sequência psuedocolumns, a referência da linguagem PL / SQL em CURRVAL e NEXTVAL oua visão geral dos conceitos de banco de dados de sequências.
A avaliação de curto-circuito deCASE
eCOALESCE()
ocorrer para seqüências quando usado no SQL? Isso está documentado?
Estamos em 11.2.0.3.5, se for do seu interesse.