Используется ли оценка короткого замыкания, описанная в документации для CASE
и COALESCE()
к последовательностям при использовании в SQL? Это, похоже, не происходит.
Документация Oracle на CASE
гласит:
База данных Oracle использует оценку короткого замыкания. Для простого выражения
CASE
... Oracle никогда не оценивает сравнение_expr, если предыдущее compare_expr равно 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
Однако при вызове из 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, если это интересно.