当列有数据时 NVL(<Column_name>,Sequence.nextval) 的奇怪行为?

Pan*_*tea 2 oracle query oracle-11g-r2 plsql sequence

我创建了一个这样的序列:

CREATE SEQUENCE seq_test2
  MINVALUE 0
  MAXVALUE 999999999999999999999999999
  START WITH 0
  INCREMENT BY 1;
Run Code Online (Sandbox Code Playgroud)

这两个查询都显示数字 0:

 select SEQ_TEST2.nextval from DUAL;   
 select SEQ_TEST2.currval from DUAL;
Run Code Online (Sandbox Code Playgroud)

我有一张桌子,你可以在这里看到:

create table STUDENT
(
  st_id      NUMBER,
  first_name VARCHAR2(150),
  last_name  VARCHAR2(150)
)
Run Code Online (Sandbox Code Playgroud)

执行下面的查询后,

select t.st_id , nvl(t.st_id , seq_test2.nextval) as seq
from STUDENT t
Run Code Online (Sandbox Code Playgroud)

当列中没有空值时st_id,我得到的结果是这样的:

    st_id    seq
   ---------------
      1       1
      2       2
      3       3
      4       4
      5       5
Run Code Online (Sandbox Code Playgroud)

当我插入列为 null 的行时st_id,执行上面的查询后,结果如下所示:

      st_id    seq
   ---------------
       1       1
       2       2
       3       3
       4       4
       5       5
       null    10
Run Code Online (Sandbox Code Playgroud)

如果我再次执行它,我会看到:

      st_id    seq
   ---------------
       1       1
       2       2
       3       3
       4       4
       5       5
       null    16
Run Code Online (Sandbox Code Playgroud)

似乎即使列st_id有数据,(seq_test2.nextval)的这一部分NVL function也会被执行!!!!为什么会发生这种情况?

提前致谢

小智 5

NVL不会短路,因此即使第一个输入不为空,也会计算第二个参数。

COALESCE是否使用短路评估

确实如此,但这并不是潘蒂亚在此描述的行为的原因。NEXTVAL对和 的引用CURRVAL不是函数而是伪列。无论您是否使用nvlor coalesce(或casedecode),sequence.nextval都将始终对每个提取的行进行评估,并且序列值将会增长。