2015-08-28 91 views
5

我想比較WHERE子句中的列col1和變量@myvar。兩者通常都包含GUID,但也可能具有NULL值。 我想我可以通過使用WHERE ISNULL(col1, '')=ISNULL(@myvar, '')解決NULL=NULL評估爲FALSE這一事實。這會比較兩個空字符串,並將其評估爲TRUE。SQL Server:唯一標識符上的ISNULL

這將然而,產生以下錯誤消息:

消息8169,級別16,狀態2,行3轉換從字符串轉換爲uniqueidentifier 時失敗。

我試圖

DECLARE @myvar uniqueidentifier = NULL 
SELECT ISNULL(@myvar,'') as col1 

同樣的錯誤消息。我試圖將一個uniqueidentifier變量 - 即使它有一個NULL值 - 轉換爲(空!)字符串,而不是其他方式,如錯誤消息所示。是什麼賦予了?

其次,有沒有更好的方法來說出我需要的WHERE子句,以便比較可能爲NULL的uniqueidentifiers?

+1

一些東西你要您的有效uniqueidentifiers也將轉換爲字符串? – shawnt00

+0

shawnt00,對於WHERE子句,非NULL uniqueidentifiers不需要轉換爲字符串。比較它們只需要評估爲TRUE,因此我只在相同位置檢索記錄。 – TVogt

回答

9

既然你是路過isnull第一個參數是不是一個字面null,它將確定調用的返回類型,在你的情況下,uniqueidentifier。第二個參數''不能轉換爲此類型,因此會出現錯誤。解決此

的一個方法是顯式檢查null S:

WHERE (@myvar IS NULL AND col1 IS NULL) OR (col1 = @myvar) 
+2

還有一個重要的部分要記住。在你將一列寫入一個函數(如ISNULL)時,查詢優化器無法發揮其潛力。看看這個(「sargable」):http://stackoverflow.com/q/799584/5089204 – Shnugo

+0

Shnugo,我甚至沒有考慮過這個。這可能會產生重要的不同,因爲所有這些都將成爲python程序的一部分,它將連續數千次(通過pyodbc)運行此查詢(或非常類似的查詢),因此節省時間他們這麼小可能會數! – TVogt

+0

@Shnugo,進一步研究了這一點,我是否有理由認爲這適用於用戶定義的函數以及內置函數......? – TVogt

2

原因ISNULL不爲你工作是,如果檢查表達真的是要使用的重置價值(價值null)必須隱式轉換爲檢查表達式的類型。

您的WHERE子句可以使用col IS NULL AND @var IS NULL來檢查該狀態。

2

正如其他人指出的那樣,從結果中排除NULL值,然後進行比較。您可以使用COALESCE從比較中排除NULL值。

+1

看看我的評論下面@Mureinik。避免函數調用(COALESCE)獲取「sargability」 – Shnugo

+0

如果使用COALESCE或ISNULL來解決問題,示例將展示如何將非sargable where子句轉換爲sargable select語句。 –

+0

COALESCE將解決我得到很好的錯誤的問題。不過,我會採取額外的潛在表現獎金。 :o)我只需要這個WHERE子句,而不是SELECT語句。 – TVogt

2

試試下面的代碼:

WHERE ISNULL([Guid], NEWID()) = @myvar 
+0

歡迎來到Stack Overflow!雖然這段代碼片段是受歡迎的,並且可能會提供一些幫助,但如果它包含* how *和* why *的解釋](// meta.stackexchange.com/q/114762),它會[大大改進],這將解決問題。請記住,你正在爲將來的讀者回答這個問題,而不僅僅是現在問的人!請編輯您的答案以添加解釋,並指出適用的限制和假設。 –

+0

由於NEWID()返回一個隨機的GUID,而不是空白的GUID,所以仍然存在將兩個空值視爲彼此不相等的問題。 –

3

我覺得下面的表達式可以用來檢查GUID欄是空的

CAST(0x0 AS UNIQUEIDENTIFIER) 

...WHERE GuidId <> CAST(0x0 AS UNIQUEIDENTIFIER)