2013-09-10 35 views
2

在SQL Server 2012中,當搜索列名稱= 'C CANTU '時,它將返回問題列= 'C CANTU'的行。SQL Server 2012在= boolean中忽略尾隨空格

這是與整理SQL_Latin1_General_CP850_BIN2

在SQL Server 2005中,這兩個值不相等,並且不返回這些行。

SQL Server 2012中是否有這樣的設置?他們是nvarchar列。每個腳本都運行相同的腳本我們正在努力升級,並因此發現最終結果不一致。

+0

順便說一句,如果列類型爲nvarchar,你爲什麼用'='C ...''而不是'= N'C ...''? –

+0

@AaronBertrand這只是一個查詢,我試圖找出不一致的原因。我確實在硬編碼字符串前面同時運行了查詢,並且沒有它/ – dko

+0

我並不是建議添加N將解決此問題。令人不安的是,您發現任何將nvarchar列與沒有N的字符串文字進行比較的查詢。這會導致各種問題 - 錯誤否定,昂貴的隱式轉換等。 –

回答

0

基本上正在發生的事情是,該列正在調整與額外的尾隨空格,以使長度匹配。一對夫婦的解決方法:

DECLARE @p NVARCHAR(255) = N'C CANTU '; 

SELECT col FROM dbo.table 
WHERE col LIKE LEFT(@p,1) + '%' AND col + 'x' = @p + 'x'; -- will seek 

SELECT col FROM dbo.table 
WHERE col = @p 
AND DATALENGTH(col) = DATALENGTH(@p); -- will seek (and add a filter) 

注意LEN()會忽略尾隨空格,但DATALENGTH()不會。

正如我在評論中提到的,我強烈建議更正您遇到的任何查詢,其中nvarchar列與字符串文字進行比較時不使用前綴N

+0

我不認爲'col +'x'= N'C CANTU'+'x''是SARGable(沒有計算列)。 –

+0

這樣比較好,但是'LIKE(@ p,1)+'%''(我認爲應該是'LIKE(@ p,1)+ N'%'' - 請參閱關於不良實踐的評論)具有較低的選擇性。 –

+0

我不喜歡這樣的評論: - | –

1

你可以使用的LIKE代替=操作:

DECLARE @MyTable TABLE(MyColumn NVARCHAR(50)); 
INSERT @MyTable (MyColumn) VALUES ('C CANTU'); 

DECLARE @param NVARCHAR(50); 
SET @param = 'C CANTU '; 

SELECT 
    t.MyColumn, 
    CASE 
     WHEN t.MyColumn = @param 
     THEN 1 
     ELSE 0 
    END AS Check1, 
    CASE 
     WHEN t.MyColumn LIKE @param 
     THEN 1 
     ELSE 0 
    END Check2, 
    CASE 
     WHEN t.MyColumn = @param AND DATALENGTH(t.MyColumn) = DATALENGTH(@param) 
     THEN 1 
     ELSE 0 
    END AS Check3 
FROM @MyTable t; 

結果:

MyColumn Check1  Check2  Check3 
-------- ----------- ----------- ----------- 
C CANTU 1   0   0 
+0

與WHERE t.text LIKE'%Decrypt'+'ByKey(%';'或'WHERE PurchaseOrderNumber LIKE'PO147%''')相同。 –