2016-05-31 212 views
6

運行MS SQL Server 2014 express。突然間,視圖中的一列變爲空,儘管是兩個不可空列的聯合。請幫我明白是怎麼回事:不可空列的聯合可爲空

enter image description here

與UNION:

enter image description here

我缺少什麼?

編輯更多的信息:當我重新保存IncomingTransactions視圖,其列現在變成零,但它不應該!以下是數量列的定義:(CASE PIN.StatusId WHEN 6 THEN PIN.QuantityReceived WHEN 7 THEN 0 ELSE PIN.QuantityRevised END)AS Quantity。每個數量字段都是非空的,case語句是詳盡無遺的。查詢的其餘部分是StatusId字段上的一個簡單聯接,它是一個非空FK,所以我仍然在這裏丟失。

編輯2:基於以下YB的建議,我創建了重現此行爲的最小的測試案例:

Create Table ybTest1 (Q1 decimal (7,2) not null, X int not null); 
GO 
Create View ybTestNSB As 
Select (CASE X WHEN 0 THEN Q1 ELSE CAST(0 as decimal(7,2)) END) AS Q From ybTest1 
GO 

在ybTest1視圖Q欄爲空,即使case語句也是面面俱到。即使我將0在ELSE分支中與CAST(0 as decimal(7,2))一起包裝,如YB所示,它仍然爲空。 CASE沒有我想到的語義,或者這是一個錯誤。

+1

奇怪的部分是Status get'not null',可能取決於數據類型。你是如何創建視圖的?我推薦使用兩個測試表進行工作,所有數據類型都爲空且不爲空,並查看是否可以重現此行爲 –

+1

您如何使用該視圖? WHERE子句?骨料?根據你的查詢,你有可能在一個表中有一個不存在於第二個表中的記錄,導致使用一個空值。 UNION進行排序併合並以消除重複。如果你想要所有的記錄,做一個聯盟所有如果你不關心重複,聯盟所有更快。 – JVC

+0

@JuanCarlosOropeza,我猜Type,Id,PartTypeId和Status都是關鍵字段?數量,FiscalYearId,DateTransacted和Source不是。 – Clay

回答

2

幾乎每個按照表達式計算的列在SQL Server中都被視爲可以爲空。解決方法是像你一樣使用ISNULL。這是在這裏computed columns section

提到的數據庫引擎自動確定基於所使用的表達式 計算列的爲空。最 表達式的結果被認爲是可空即使僅非空列 是本...那是可空的表達可以通過指定ISNULL(check_expression, constant), 其中常數爲任何空結果取代的非空值變成非空 一個。

但它適用於任何由於計算(包括視圖定義)而導出列的情況。

很少或根本沒有邏輯來分析空值是否實際上是可能的(有時比看起來更困難,因爲各種不推薦使用的set選項可能會導致null而不是溢出錯誤,所以即使1 + X在您的示例中可能會產生null)謹慎的一面。我不認爲你的case表達式實際上可以輸出null,但根據我的經驗,除了isnull中包含的那些外,任何計算列都將被視爲可以爲空。

因此,在您的測試情況下,你可以取代

Create View ybTestNSB As 
Select (CASE X WHEN 0 THEN Q1 ELSE CAST(0 as decimal(7,2)) END) AS Q From ybTest1 

隨着

Create View ybTestNSB As 
Select ISNULL(CASE X WHEN 0 THEN Q1 END, 0) AS Q From ybTest1 

爲了避免把一個惱人的完全冗餘的表達中。

+0

這似乎是Martin的情況,但它沒有[記錄爲這樣](https://msdn.microsoft.com/en-us/library/ms181765.aspx?f=255&MSPPError=-2147217396)。 Quote:「如果沒有input_expression = when_expression評估爲TRUE,則SQL Server數據庫引擎在指定ELSE子句時返回else_result_expression,如果未指定ELSE子句,則返回NULL值。」簡單和搜索的病例陳述也是如此。在我的示例中,ELSE子句顯然不爲空。 – naasking

+0

@naasking是的,實際上你的'case'表達式不能返回null。但是很少或根本沒有邏輯來分析這一點。幾乎任何計算列都將被視爲可空,除了包含isnull的列。 –

+1

好的,奇怪的是它並不是在2008 R2中推斷出NULL,而是在2014年這樣做。我們現在再次檢查了這一點,所以看起來MSSQL 2014比2008年的精確度要低。這個答案必須做,謝謝。 – naasking