2009-07-10 85 views
2

nvl()函數可以級聯,...它在IBM採訪中被問及我......爲什麼?NVL功能可以級聯嗎?

+0

,我們談論的Oracle的NVL功能?當他們說「級聯」時,它們是什麼意思? – 2009-07-10 11:26:13

+0

是oracle nvl和級聯意味着nvl內的nvl – hrishi 2009-07-10 11:35:02

回答

3

爲什麼不呢?例如:

select NVL(null, NVL(null, 1)) from dual 

它可以是這樣的:

select NVL(delete_date, NVL(edit_date, create_date)) AS last_change 
from Table 

可能他們想讓你說,這是確定的功能。所以它是可重入的。

+0

儘管如此,不需要嵌套它。 `NVL(delete_date,edit_date,create_date)`會做同樣的事情。 – Thilo 2011-09-02 10:23:55

8

我的回答:

是,NVL可以級聯。這是我期望從代碼移植到Oracle版本(包括8i)的代碼,因爲在Oracle 9i之前不支持COALESCE。

COALESCE是一個ANSI SQL 99標準,其工作原理類似於CASE/SWITCH語句,它按順序評估每個表達式,並且在它遇到非空表達式時不繼續計算表達式。這被稱爲短路。使用COALESCE的另一個好處是數據類型不需要匹配,這在使用NVL時是必需的。

此:

SELECT COALESCE(1.5/NULL, 
       SUM(NULL), 
       TO_CHAR(SYSDATE, 'YYYY')) abc 
    FROM DUAL 

...將返回:2009(今後〜32天,反正)

1

,我已經看到了級聯NVL的最常見的原因是數據庫隨着時間的推移而變化。 原始設計有一張表格,後來被更改爲表格中有更多列。 Alter語句將新列創建爲NULL,並且這是利用了視圖的優勢,因此頂部的 代碼無需更改。問題在於單個列change_date, 被替換爲多個列。 Update_Date,Comment_Date和Approval_date。在 3個新列的每一個現在合併得到視圖中的「CHANGE_DATE」與

create or replace view OldTableNmae as 
select other_columns 
    , nvl (update_date, nvl (comment_date, approval_date)) change_date 
    , more_columns 
from new_table 
/
1

正如有人說,NVL可以級聯,但首選的解決方案是使用COALESCE代替。然而,這兩個功能都沒有完全互換:

1)如在別處所提到的,COALESCE僅直至符合一個不計算爲NULL評估來自所述第一參數

2)然而,COALESCE要求所有參數具有相同的數據類型,因此與NVL相比,其將是STRICTER,NVL將首先嚐試隱式轉換。

例如

SELECT COALESCE(1.5/NULL, 
      SUM(NULL), 
      TO_CHAR(SYSDATE, 'YYYY')) abc 
FROM DUAL 

其實引發錯誤ORA-00932: inconsistent datatypes: expected NUMBER got CHAR

NVL將改爲返回本年度

SELECT NVL(1.5/NULL, 
      NVL(SUM(NULL), 
       TO_CHAR(SYSDATE, 'YYYY'))) abc 
FROM DUAL 

其他例子:

select coalesce('some text',sysdate) from dual; 

拋出ORA-00932: inconsistent datatypes: expected CHAR got DATE,而

select nvl('some text',sysdate) from dual; 

回報some text,但

select nvl(sysdate,'some text') from dual; 

拋出ORA-01841: (full) year must be between -4713 and +9999, and not be 0(因爲 '一些文本' 的隱式轉換嘗試的日期已失敗)