2014-10-03 26 views
2

SQL Server標準64位使用歸類SQL_Latin1_General_CP1_CS_AS爲什麼使用區分大小寫歸類時,範圍上的過濾與錯誤的大小寫匹配?

plz

ort varchar(30) SQL_Latin1_General_CP1_CS_AS 
select ort, 
from plz 
where 
    ort >= 'zürich' 
    and ort <= 'zürichz' 

選擇這樣的數據:

Zürich 
Zürich Mülligen 
Zürich 80 

沒有z在第二蘇黎世的端部沒有數據被選中,這是可以的。但爲什麼它會在區分大小寫的服務器上顯示數據?

+0

僅供參考,我更新了我的答案是既描述和更清晰示例代碼。 – 2015-02-05 18:27:05

回答

2

比較字符串時,第一件事是SQL Server會之一,是墊較短的字符串用空格,使字符串的長度是相同的。所以基本上你查詢試圖找到匹配zürich任何字符串,然後下一個字符必須是一個可以(從你的第二個字符串)(從你的第一個字符串)和z之間出現 - 包括本身,最字母字符。

這有什麼好做區分大小寫。

如果第二個字符串中沒有z,那麼匹配的唯一字符串將是值爲zürich的字符串,並且只是尾隨空格。

+2

我相信OP詢問爲什麼'_CS_AS'小寫的'z'與大寫'Z'匹配。 – GSerg 2014-10-03 09:25:58

+0

@GSerg和Damien:關於先用空格填充是真的,但這不是O.P.所要求的。他們問爲什麼任何以大寫字母「Z」開頭的單詞都會包含在結果中,錯誤地認爲大小寫敏感的整理會排除它們。如果區分大小寫不是一個因素,那麼「蘇黎世」也會匹配,並且不會/不可以(O.P.必須誤導結果)。我已經更新了我的答案,以便更清楚地瞭解這個問題。 – 2015-02-05 18:23:41

2

有兩個混淆發生在這裏:

  • 平等VS排序

    當使用相等運算=區分大小寫的問題更直接的和明顯的(如「Z 「<>」Z「)。但使用><運營商排序時是必需的,這是由單獨的,雖然受以下因素影響,區分大小寫VS不區分大小寫的。排序是由類型排序的(見下點),然後可能由大小寫確定的第一確定。

  • 字典順序VS二進制(即ASCII值/碼點)順序

    詞典排序,默認值,意味着一個特定的語言字母順序將被使用。特定語言是排序規則名稱的一部分,如Latin1_GeneralDanish。這將在兩者之後放置「a」(ASCII = 97)和「A」(ASCII = 65),並放置「Z」(ASCII = 90)。二進制排序(即,一個在_BIN_BIN2結束)將使用二進制字符值,這將使「Z」,「A」和「a」之間。二進制排序必須區分大小寫,因爲它是一切敏感的。字典排序會將「A」和「a」組合在一起,但如果排序規則也區分大小寫,它只會強制「A」出現在「a」之前。不區分大小寫的字典排序可以混合使用「A」和「a」值(請參閱示例中的最後一個SELECT)。

現在讓我們把這一切都回到問題。當前整理是SQL_Latin1_General_CP1_CS_AS這是一個詞典排序。在查字典時,蘇黎世蘇黎世將被發現背靠背; 蘇黎世不會來之前zany只是因爲它有一個資本Z

看着您的查詢返回的結果,第一個條目蘇黎世不應該在那裏。我無法得到這個回報。由於這是一個區分大小寫的排序規則,因此蘇黎世確實會在蘇黎世之前出現,並且會被WHERE子句過濾掉。但其他兩個值蘇黎世Mülligen蘇黎世80是有效的返回,因爲他們確實符合WHERE條款。如果你希望它們不匹配,那麼你需要使用二進制排序而不是區分大小寫的字典。

要看到這個動作,運行以下命令:

字典(不區分大小寫):

SELECT tmp.val 
FROM (SELECT 'bat' 
     UNION ALL 
     SELECT 'bar' 
     UNION ALL 
     SELECT 'bad' 
     UNION ALL 
     SELECT 'Bar') tmp(val) 
ORDER BY tmp.val COLLATE SQL_Latin1_General_CP1_CI_AS ASC; 

結果:


酒吧
酒吧 - - 「酒吧」通常但不一定在「酒吧」之後3210 蝙蝠

字典(區分大小寫):

SELECT tmp.val 
FROM (SELECT 'bat' 
     UNION ALL 
     SELECT 'bar' 
     UNION ALL 
     SELECT 'bad' 
     UNION ALL 
     SELECT 'Bar') tmp(val) 
ORDER BY tmp.val COLLATE SQL_Latin1_General_CP1_CS_AS ASC; 

結果:


酒吧 - 「酒吧」 必然到來之前 「酒吧」,但之前不好「,甚至」b「
bar
bat

二進制:

SELECT tmp.val 
FROM (SELECT 'bat' 
     UNION ALL 
     SELECT 'bar' 
     UNION ALL 
     SELECT 'bad' 
     UNION ALL 
     SELECT 'Bar') tmp(val) 
ORDER BY tmp.val COLLATE Latin1_General_BIN2 ASC; 

結果:

酒吧 - 「酒吧」( 「B」 值= 66)一定來之前 「B」(值= 98)

bar
bat


要更好地瞭解區分大小寫如何影響篩選和排序,請運行以下分步示例。

DECLARE @test TABLE (string VARCHAR(30) 
         COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL); 
INSERT INTO @test (string) values ('A'); 
INSERT INTO @test (string) values ('B'); 
INSERT INTO @test (string) values ('Y'); 
INSERT INTO @test (string) values ('Z'); 
INSERT INTO @test (string) values ('a'); 
INSERT INTO @test (string) values ('b'); 
INSERT INTO @test (string) values ('y'); 
INSERT INTO @test (string) values ('z'); 

-- case-sensitive, dictionary ordered sorting via column collation 
SELECT [string] AS [Test1] FROM @test ORDER BY string ASC; 
/* -- upper-case and lower-case of each letter are grouped together; 
    -- upper-case consistently comes first due to case-sensitive 
A 
a 
B 
b 
Y 
y 
Z 
z 
*/ 

-- case-sensitive comparison via column collation 
SELECT [string] AS [Test2] FROM @test WHERE string = 'Y'; 
/* -- equality is straight-forward when using case-sensitive comparison 
Y 
*/ 

-- case-sensitive, dictionary ordered comparison and sorting via column collation 
SELECT [string] AS [Test3] FROM @test WHERE string >= 'Y' ORDER BY string ASC; 
/* -- upper-case comes first due to case-sensitive 
Y 
y 
Z 
z 
*/ 

-- case-sensitive, dictionary ordered comparison and sorting via column collation 
SELECT [string] AS [Test4] FROM @test WHERE string >= 'y' ORDER BY string ASC; 
/* -- upper-case comes first due to case-sensitive 
y 
Z 
z 
*/ 

-- case-insensitive, dictionary ordered comparison via collation override 
SELECT [string] AS [Test5] FROM @test 
WHERE string > 'Y' COLLATE SQL_Latin1_General_CP1_CI_AS; 
/* -- upper-case and lower-case are the same due to case-INsensitive 
Z 
z 
*/ 

-- binary ordering via collation override 
SELECT [string] AS [Test6] FROM @test ORDER BY string COLLATE Latin1_General_BIN ASC; 
/* 
A 
B 
Y 
Z 
a 
b 
y 
z 
*/ 

-- case-sensitive, dictionary ordered comparison via column collation; 
-- binary ordering via collation override 
SELECT [string] AS [Test7] FROM @test WHERE string >= 'y' 
    ORDER BY string COLLATE Latin1_General_BIN ASC; 
/* -- lower-case 'y' comes before both 'Z' and 'z' when using a dictionary comparison 
Z 
y 
z 
*/ 

-- binary comparison via collation override; 
-- binary ordering via collation override 
SELECT [string] AS [Test8] FROM @test WHERE string >= 'y' COLLATE Latin1_General_BIN 
    ORDER BY string COLLATE Latin1_General_BIN ASC; 
/* -- lower-case 'y' comes after all capitals when using a binary comparison 
y 
z 
*/ 

-- case-insensitive, dictionary ordered sorting via collation override 
SELECT [string] AS [Test9] FROM @test 
ORDER BY string COLLATE SQL_Latin1_General_CP1_CI_AS ASC; 
/* -- upper-case and lower-case of each letter are grouped together, 
    -- but inconsistent for upper-case vs lower-case first 
A 
a 
b 
B 
Y 
y 
z 
Z 
*/ 

見一些SQL Server排序規則信息下面的鏈接: