Оценка короткого замыкания CASE и COALESCE работает с последовательностями в PL / SQL, но не в SQL

Выполнена ли оценка короткого замыкания, описанная в документации дляCASE а такжеCOALESCE() применять к последовательностям при использовании в SQL? Это, кажется, не происходит.

Оракулдокументация поCASE говорится, что:

База данных Oracle использует оценку короткого замыкания. Для простогоCASE выражение ... Oracle никогда не оценивает сравнение_экспресс, если предыдущий сравнение_экспресс равно expr. Для искомого выражения CASE база данных ... никогда не оценивает условие, если предыдущее условие было истинным.

Аналогично дляCOALESCE() документация говорится, что:

База данных Oracle использует оценку короткого замыкания. База данных оценивает каждое значение expr и определяет, является ли оно NULL, вместо того, чтобы оценивать все значения expr, прежде чем определять, является ли какое-либо из них NULL.

При вызове последовательности из SQL это не так; как видите, короткое замыкание не происходит, и последовательность увеличивается.

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.

Однако при вызове из PL / SQL последовательностьне увеличивается:

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

Вызов последовательности в SQL из PL / SQL приводит к тем же результатам, что и в 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

Кажется, в документации нет ничего об этом;Руководство администратора по управлению последовательностями, ссылка на язык SQL для последовательности psuedocolumns, ссылка на язык PL / SQL в CURRVAL и NEXTVAL или жеобзор концепций базы данных последовательностей.

Оценка короткого замыканияCASE а такжеCOALESCE() происходят для последовательностей при использовании в SQL? Это задокументировано?

Мы на 11.2.0.3.5, если это интересно.

Ответы на вопрос(2)

Ваш ответ на вопрос