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

SQL Fiddle.

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.

questionAnswers(2)

yourAnswerToTheQuestion