Oracle

當列有數據時 NVL(<Column_name>,Sequence.nextval) 的奇怪行為?

  • June 29, 2021

我創建了一個這樣的序列:

CREATE SEQUENCE seq_test2
 MINVALUE 0
 MAXVALUE 999999999999999999999999999
 START WITH 0
 INCREMENT BY 1;

這兩個查詢都向我顯示數字 0:

select SEQ_TEST2.nextval from DUAL;   
select SEQ_TEST2.currval from DUAL;

我有一張桌子,你可以在這裡看到:

create table STUDENT
(
 st_id      NUMBER,
 first_name VARCHAR2(150),
 last_name  VARCHAR2(150)
)

執行下面的查詢後,

select t.st_id , nvl(t.st_id , seq_test2.nextval) as seq
from STUDENT t

當 column 中沒有 null 時st_id,我得到的結果是:

   st_id    seq
  ---------------
     1       1
     2       2
     3       3
     4       4
     5       5

當我插入列為空的行時st_id,執行上面的查詢後,結果如下:

     st_id    seq
  ---------------
      1       1
      2       2
      3       3
      4       4
      5       5
      null    10

如果我再次執行它,我會看到:

     st_id    seq
  ---------------
      1       1
      2       2
      3       3
      4       4
      5       5
      null    16

好像即使列st_id有數據,這部分NVL function(seq_test2.nextval) 也會被執行!!!為什麼會這樣?

提前致謝

NVL不會短路,因此即使第一個輸入不為空,也會評估第二個參數。

COALESCE確實使用短路評估

沒錯,但這不是 Pantea 在這裡描述的行為的原因。NEXTVAL對and的引用CURRVAL不是函式,而是偽列。無論您是否使用nvlor coalesce(或caseor decode),sequence.nextval都將始終針對每個獲取的行進行評估,並且序列值將會增長。

NVL不會短路,因此即使第一個輸入不為空,也會評估第二個參數。

COALESCE確實使用短路評估

–edit 不過沒關係,看看 Andi Schloegl 的回答

引用自:https://dba.stackexchange.com/questions/294981