oracle 使用nullif解決除數為零的問題

nayi_224發表於2018-05-25

先來說一下nullif的語法。
這裡寫圖片描述

NULLIF compares expr1 and expr2. If they are equal, then the function returns null. If they are not equal, then the function returns expr1. You cannot specify the literal NULL for expr1.

If both arguments are numeric data types, then Oracle Database determines the argument with the higher numeric precedence, implicitly converts the other argument to that data type, and returns that data type. If the arguments are not numeric, then they must be of the same data type, or Oracle returns an error.

The NULLIF function is logically equivalent to the following CASE expression:
CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END

如果兩個引數相等,返回null,否則返回第一個。第一個引數不可指定為空。對於非數字型別引數,資料型別必須一致。對於數值資料型別,會隱式的轉化為更高優先順序的資料型別。(這個理解可能有誤,我測試了int,integer,float。但是最終都轉化為number型別)。

一般來說,我們處理“除數為零”的問題會用到decode(當然也可以用case,但是寫起來程式碼更多些)。比如

dividend / decode(divisor, 0, null, divisor)

但是在除數divisor非常複雜的時候,就需要把這一大串程式碼寫兩遍,或者是再套一層view。無論是哪種,都是極其不利於維護的。

1 / 
decode((sum(t.val) over(order by t.c) +
       nvl(lead(val) over(partition by b order by c), 0)) /
      sum(val) over(partition by b order by c),
      0,
      null,
      (sum(t.val) over(order by t.c) +
       nvl(lead(val) over(partition by b order by c), 0)) / sum(val)
      over(partition by b order by c))

對於這種複雜表示式的除數,每回修改都要改兩遍,很容易出錯。

利用nullif,可以讓除數只寫一次。
因為 decode(divisor, 0, null, divisor)nullif(divisor, 0) 是等效的。

相關文章