ฉันได้ตั้งค่าการเปรียบเทียบฐานข้อมูลเป็นLatin1_General_BIN
เพื่อทำการเปรียบเทียบสตริงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ สิ่งนี้จะส่งผลกระทบต่อประสิทธิภาพหรือไม่ มันจะมีผลกระทบกับการดำเนินงาน DML หรือ DDL ในฐานข้อมูลหรือไม่ ฐานข้อมูลมีอยู่แล้วในตาราง
ฉันได้ตั้งค่าการเปรียบเทียบฐานข้อมูลเป็นLatin1_General_BIN
เพื่อทำการเปรียบเทียบสตริงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ สิ่งนี้จะส่งผลกระทบต่อประสิทธิภาพหรือไม่ มันจะมีผลกระทบกับการดำเนินงาน DML หรือ DDL ในฐานข้อมูลหรือไม่ ฐานข้อมูลมีอยู่แล้วในตาราง
คำตอบ:
การเรียงใน SQL Serverกำหนดกฎสำหรับการจับคู่และการเรียงลำดับข้อมูลอักขระ โดยปกติคุณจะต้องเลือกการเรียงลำดับแรกตามความหมายของการเปรียบเทียบและเรียงลำดับตามที่ผู้บริโภคต้องการข้อมูล
โดยทั่วไปแล้วมนุษย์ไม่พบว่าการเปรียบเทียบไบนารีจะสร้างพฤติกรรมการเรียงลำดับและการเปรียบเทียบที่พวกเขาคาดหวัง ดังนั้นแม้ว่าสิ่งเหล่านี้จะให้ประสิทธิภาพที่ดีที่สุด (โดยเฉพาะอย่างยิ่งเวอร์ชัน BIN2 จุดรหัสบริสุทธิ์) การใช้งานส่วนใหญ่ไม่ได้ใช้
ถัดไปในแง่ประสิทธิภาพดิบ ( แต่สำหรับสตริงที่ไม่ใช่ Unicode) เป็นความเข้ากันได้ย้อนหลังcollations SQL เมื่อทำงานกับข้อมูล Unicode การเปรียบเทียบเหล่านี้จะใช้การเปรียบเทียบ Windowsแทนพร้อมกับประสิทธิภาพการทำงานที่เหมือนกัน ที่นี่มีกับดักที่บอบบางดังนั้นคุณต้องมีเหตุผลที่ดีในการเลือกการเปรียบเทียบ SQL ในวันนี้ (ยกเว้นกรณีที่ทำงานในระบบของสหรัฐอเมริกาซึ่งยังคงเป็นค่าเริ่มต้น)
โดยทั่วไป Windows collations นั้นช้าที่สุดเนื่องจากการเปรียบเทียบ Unicode ที่ซับซ้อนและกฎการเรียงลำดับ อย่างไรก็ตามข้อเสนอเหล่านี้เข้ากันได้อย่างสมบูรณ์กับ Windows ใน SQL Server และได้รับการปรับปรุงอย่างสม่ำเสมอเพื่อให้ทันกับการเปลี่ยนแปลงในมาตรฐาน Unicode สำหรับการใช้งานที่ทันสมัยซึ่งมีข้อมูล Unicode แนะนำให้ใช้การเปรียบเทียบ Windows
TL; DR
หากสิ่งที่คุณต้องการคือการเปรียบเทียบและการเรียงลำดับความหมายแบบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่คุณควรเลือกรูปแบบ_CS_
(สำหรับกรณีที่ละเอียดอ่อน) ของการเปรียบเทียบฐานใดก็ตามให้ลักษณะการทำงานที่คาดไว้สำหรับภาษาและวัฒนธรรมของผู้ใช้ ตัวอย่างเช่นทั้งสองแบบนี้เป็นตัวพิมพ์เล็กและตัวพิมพ์ใหญ่:
-- Latin1-General, case-sensitive, accent-sensitive
Latin1_General_CS_AS
-- Latin1-General, case-sensitive, accent-sensitive for Unicode Data,
-- SQL Server Sort Order 51 on Code Page 1252 for non-Unicode Data
SQL_Latin1_General_CP1_CS_AS
คุณสามารถดูคำจำกัดความเหล่านี้ได้โดยใช้sys.fn_helpcollations
สี่ตารางที่เหมือนกันยกเว้นการเปรียบเทียบ; หนึ่งไบนารีหนึ่งตัวพิมพ์เล็กและตัวพิมพ์ใหญ่หนึ่งตัว
CREATE TABLE #Example_BIN
(
string nvarchar(50)
COLLATE Latin1_General_BIN
NOT NULL
);
CREATE TABLE #Example_CS
(
string nvarchar(50)
COLLATE Latin1_General_CS_AI
NOT NULL
);
CREATE TABLE #Example_CI
(
string nvarchar(50)
COLLATE Latin1_General_CI_AI
NOT NULL
);
CREATE TABLE #Example_SQL
(
string varchar(50) -- Note varchar
COLLATE SQL_Latin1_General_CP1_CS_AS
NOT NULL
);
ข้อมูลตัวอย่างเดียวกันสำหรับแต่ละตาราง:
INSERT #Example_BIN
(string)
VALUES
(N'A'),
(N'a'),
(N'B'),
(N'b'),
(N'C'),
(N'c');
INSERT #Example_CS
SELECT EB.string
FROM #Example_BIN AS EB;
INSERT #Example_CI
SELECT EB.string
FROM #Example_BIN AS EB;
INSERT #Example_SQL
SELECT EB.string
FROM #Example_BIN AS EB;
ตอนนี้เราต้องการค้นหาสตริงที่มากกว่า 'a':
SELECT EB.string AS BIN
FROM #Example_BIN AS EB
WHERE EB.string > N'a'
ORDER BY EB.string;
SELECT EC.string AS CS
FROM #Example_CS AS EC
WHERE EC.string > N'a'
ORDER BY EC.string;
SELECT EC2.string AS CI
FROM #Example_CI AS EC2
WHERE EC2.string > N'a'
ORDER BY EC2.string;
SELECT ES.string AS SQL
FROM #Example_SQL AS ES
WHERE ES.string > 'a' -- not Unicode
ORDER BY ES.string;
╔═════╗
║ BIN ║
╠═════╣
║ b ║
║ c ║
╚═════╝
╔════╗
║ CS ║
╠════╣
║ A ║
║ b ║
║ B ║
║ c ║
║ C ║
╚════╝
╔════╗
║ CI ║
╠════╣
║ B ║
║ b ║
║ C ║
║ c ║
╚════╝
╔═════╗
║ SQL ║
╠═════╣
║ B ║
║ b ║
║ C ║
║ c ║
╚═════╝
โปรดทราบว่าหากเราใช้ Unicode ตามตัวอักษรกับการเปรียบเทียบ SQL กฎการแปลงโดยนัยส่งผลให้เกิดการเปรียบเทียบการเปรียบเทียบกับ Windows:
SELECT ES.string AS SQL
FROM #Example_SQL AS ES
WHERE ES.string > N'a'
ORDER BY ES.string;
... และผลลัพธ์การเปรียบเทียบ SQL เปลี่ยนไป :
╔═════╗
║ SQL ║
╠═════╣
║ A ║
║ B ║
║ b ║
║ C ║
║ c ║
╚═════╝
ระบุว่านี่เป็นฐานข้อมูลที่มีอยู่แล้วซึ่งมีตารางที่กำหนดไว้แล้วมีบางอย่างที่เกี่ยวข้องกับการกระทำของการเปลี่ยนแปลงการจัดเรียงฐานข้อมูลเกินกว่าผลกระทบต่อประสิทธิภาพที่อาจเกิดขึ้นกับการดำเนินการ DML (ซึ่งจริงๆแล้วมีอยู่แล้ว) มีผลกระทบอย่างแท้จริงต่อประสิทธิภาพและการทำงานและการเปลี่ยนแปลงนี้ไม่เพียง แต่ไม่บรรลุเป้าหมายที่กำหนดไว้ (อย่างน้อยก็ไม่สม่ำเสมอ) แต่ก็น่าจะเปลี่ยนพฤติกรรม (หรือจะเปลี่ยนแปลงพฤติกรรมเมื่อสร้างตารางใหม่) ในแง่ของ วิธีการสั่งซื้อและบรรจุข้อมูล
พอลได้อธิบายและตัวอย่างที่ดีเกี่ยวกับความแตกต่างของประสิทธิภาพและพฤติกรรมระหว่างการเปรียบเทียบประเภทต่าง ๆ ในคำตอบของเขาดังนั้นฉันจะไม่พูดซ้ำอีก อย่างไรก็ตามจุดสองสามจุดต้องการรายละเอียดเพิ่มเติมและมีจุดอื่น ๆ อีกหลายจุดที่จะเพิ่มตามสถานการณ์ปัจจุบันของการเปลี่ยนการจัดเรียงของฐานข้อมูลที่มีอยู่ซึ่งตรงข้ามกับการตั้งค่าการเปรียบเทียบฐานข้อมูลใหม่
การเปรียบเทียบไบนารีเป็นมากกว่าตัวพิมพ์เล็กและตัวพิมพ์ใหญ่: ทุกอย่างละเอียดอ่อน! ดังนั้นโดยใช้การเปรียบเทียบไบนารี (สิ้นสุดใน_BIN
หรือ_BIN2
) การเปรียบเทียบของคุณตอนนี้ยังเน้นสำเนียง, kana สำคัญไวไวด์ ธ และกลูเตนไว (อย่างน้อยที่ดูเหมือนจะเป็นแนวโน้มวันนี้ ;-)) นี่คือผลกระทบที่ต้องการในการเปลี่ยนแปลงนี้หรือไม่? ผู้ใช้ปลายทางคาดหวังว่าจะมีการเปลี่ยนแปลงพฤติกรรมนี้หรือไม่?
การจัดเรียงมีผลต่อการเปรียบเทียบไม่เพียง แต่ยังรวมถึงการเรียงลำดับ การเปรียบเทียบไบนารีจะเรียงลำดับตามASCII
หรือUNICODE
ค่าไบต์ (ขึ้นอยู่กับVARCHAR
หรือNVARCHAR
ตามลำดับ) ของแต่ละไบต์ ดังนั้นโดยการเลือกการเปรียบเทียบแบบไบนารีคุณกำลังละทิ้งกฎการกำหนดน้ำหนักเฉพาะภาษา / วัฒนธรรมที่สั่งตัวละครแต่ละตัว (แม้กระทั่งตัวละครในบางภาษาเช่นฮังการีซึ่งประกอบด้วย 2 ตัวอักษร) ตามตัวอักษรของวัฒนธรรมนั้น ดังนั้นถ้า "ch" ควรมาหลังจาก "k" ตามธรรมชาติแล้วนั่นจะไม่เกิดขึ้นโดยใช้การเปรียบเทียบแบบไบนารี นี่เป็นผลกระทบที่ต้องการจากการเปลี่ยนแปลงนี้อีกหรือไม่ ผู้ใช้ปลายทางคาดหวังว่าจะมีการเปลี่ยนแปลงพฤติกรรมนี้หรือไม่?
หากคุณไม่มีข้อกำหนดเฉพาะด้านความเข้ากันได้แบบย้อนหลังสำหรับแอปพลิเคชันของคุณคุณควรใช้BIN2
แทนการBIN
เปรียบเทียบโดยสมมติว่าคุณต้องการเรียงแบบไบนารีในตอนแรก การBIN2
เปรียบเทียบถูกนำมาใช้ใน SQL Server 2005 และตามหน้า MSDN สำหรับแนวทางการใช้การเปรียบเทียบ BIN และ BIN2 :
การเปรียบเทียบไบนารีก่อนหน้านี้ใน SQL Server ที่ลงท้ายด้วย "_BIN" ได้ทำการเปรียบเทียบรหัสแบบจุดต่อจุดรหัสที่ไม่สมบูรณ์สำหรับข้อมูล Unicode SQL Server ไบนารีที่เก่ากว่าเปรียบเทียบอักขระตัวแรกเป็น WCHAR ตามด้วยการเปรียบเทียบแบบไบต์ต่อไบต์
...
คุณสามารถย้ายไปยัง [_BIN2] การเปรียบเทียบแบบไบนารีเพื่อใช้ประโยชน์จากการเปรียบเทียบจุดรหัสที่แท้จริงและคุณควรใช้การเปรียบเทียบแบบไบนารีใหม่สำหรับการพัฒนาแอปพลิเคชันใหม่
ควรสังเกตว่าการ_BIN2
เปรียบเทียบจะสะดวกตรงกับลักษณะการทำงานของOrdinal
ตัวเลือกของStringComparison Enumerationเช่นการเปรียบเทียบและการเรียงลำดับที่ทำในรหัส. NET โดยใช้ตัวเลือกนั้นจะให้ผลลัพธ์เดียวกันกับการดำเนินการเดียวกันกับ SQL Server (เมื่อใช้งาน) แน่นอนการ_BIN2
เปรียบเทียบ)
สำหรับเหตุผลที่คล้ายกับสิ่งที่เพิ่งได้รับการกล่าวเกี่ยวกับการ_BIN2
เรียงเว้นแต่คุณจะมีความต้องการที่เฉพาะเจาะจงในการรักษาพฤติกรรมย้อนกลับเข้ากันได้คุณควรยันต่อโดยใช้การเปรียบเทียบของ Windows และไม่ SQL collations เซิร์ฟเวอร์เฉพาะ (คือคนที่เริ่มต้นด้วยการSQL_
ได้รับการพิจารณาในขณะนี้ ค่อนข้าง "sucky" ;-))
เมื่อใช้ข้อมูล Unicode (เช่นสตริงนำหน้าด้วยN
หรือเข้ามาใน SQL Server จากรหัสแอปที่ระบุประเภทข้อมูลเป็นNChar
หรือNVarChar
) ฉันไม่เห็นว่าการใช้การเปรียบเทียบหนึ่งกับอื่นจะสร้างความแตกต่างสำหรับการแทรกหรือการปรับปรุงNCHAR
หรือNVARCHAR
เขตข้อมูลสตริง .
เมื่อใช้ข้อมูลที่ไม่ใช่ Unicode หรือแทรกหรืออัปเดตฟิลด์ที่ไม่ใช่ Unicode ดังนั้นการเปรียบเทียบ (ฐานข้อมูลหรือฟิลด์) อาจมีบทบาทเล็ก ๆ หากอักขระใด ๆ ที่ถูกแทรก / อัปเดตจำเป็นต้องได้รับการแปลหรือไม่สามารถทำแผนที่ได้ แม้แต่คำเดียว?) ตามที่ระบุไว้ในหน้ารหัสที่กำหนดโดยการเปรียบเทียบ แน่นอนว่าอาจมีปัญหานี้เกิดขึ้นเมื่อใดก็ตามที่มีการใช้ข้อมูลหรือชนิดข้อมูลที่ไม่ใช่ Unicode และไม่เฉพาะกับสถานการณ์นี้ในการเปลี่ยนการเปรียบเทียบฐานข้อมูล การเปลี่ยนแปลงนั้นจะส่งผลกระทบต่อตัวอักษรของสตริง (ซึ่งอาจเป็นปัญหาหากการเปรียบเทียบฐานข้อมูลแตกต่างจากการเปรียบเทียบของเขตข้อมูล) แต่แม้ว่าจะไม่มีการเปลี่ยนแปลงใด ๆ กับการเปรียบเทียบฐานข้อมูลที่มาจากฐานข้อมูลอื่นหรือจากภายนอกเซิร์ฟเวอร์ SQL (รหัสลูกค้าใด ๆ ) สามารถมีอักขระใด ๆ และมีการเข้ารหัสเฉพาะใด ๆ
สำคัญมาก!!! เมื่อเปลี่ยนการเปรียบเทียบค่าเริ่มต้นของฐานข้อมูลการเปรียบเทียบที่ระบุสำหรับฟิลด์สตริงที่มีอยู่ในตารางใด ๆ ที่มีอยู่จะไม่เปลี่ยนแปลง แต่ฟิลด์ใหม่ใด ๆจะมีการเปรียบเทียบค่าเริ่มต้นของฐานข้อมูล (เว้นแต่จะถูกเขียนทับผ่านส่วนCOLLATE
คำสั่ง) สิ่งนี้จะส่งผลต่อข้อความค้นหาของคุณในสามวิธี:
1)หากมีข้อสงสัยใด ๆ เข้าร่วมในเขตข้อมูลที่มีอยู่เหล่านั้นไปยังเขตข้อมูลใหม่ใด ๆ คุณจะได้รับข้อผิดพลาดการเปรียบเทียบไม่ตรงกัน:
USE [master];
GO
IF (DB_ID(N'ChangeCollationTest') IS NOT NULL)
BEGIN
PRINT 'Dropping [ChangeCollationTest] DB...';
ALTER DATABASE [ChangeCollationTest]
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE;
DROP DATABASE [ChangeCollationTest];
END;
GO
PRINT 'Creating [ChangeCollationTest] DB...';
CREATE DATABASE [ChangeCollationTest]
COLLATE SQL_Latin1_General_CP1_CI_AS;
GO
USE [ChangeCollationTest];
GO
CREATE TABLE [CollateTest-SQL_Latin1_General_CP1_CI_AS]
(Col1 NVARCHAR(50) COLLATE DATABASE_DEFAULT, Col2 NVARCHAR(50));
SELECT *
FROM sys.columns sc
WHERE sc.[object_id] = OBJECT_ID(N'[CollateTest-SQL_Latin1_General_CP1_CI_AS]');
-- "collation_name" for both fields shows: SQL_Latin1_General_CP1_CI_AS
GO
USE [master];
GO
ALTER DATABASE [ChangeCollationTest]
COLLATE Latin1_General_BIN2;
GO
USE [ChangeCollationTest];
GO
CREATE TABLE [CollateTest-Latin1_General_BIN2]
(Col1 NVARCHAR(50) COLLATE DATABASE_DEFAULT, Col2 NVARCHAR(50));
SELECT *
FROM sys.columns sc
WHERE sc.[object_id] = OBJECT_ID(N'[CollateTest-Latin1_General_BIN2]');
-- "collation_name" for both fields shows: Latin1_General_BIN2
GO
SELECT *
FROM dbo.[CollateTest-SQL_Latin1_General_CP1_CI_AS] ctSQL
INNER JOIN dbo.[CollateTest-Latin1_General_BIN2] ctWIN
ON ctWIN.Col1 = ctSQL.Col1;
ผลตอบแทน:
Msg 468, Level 16, State 9, Line 4
Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and
"Latin1_General_BIN2" in the equal to operation.
2) เพรดิเคต / ตัวกรองในฟิลด์ที่มีอยู่ของตารางที่มีอยู่ (ตั้งค่าเป็นการเปรียบเทียบค่าเริ่มต้นก่อนหน้า) ที่เปรียบเทียบกับตัวอักษรสตริงหรือตัวแปรจะไม่มีข้อผิดพลาด แต่แน่นอนว่าพวกเขาอาจได้รับผลกระทบ ทั้งสองข้างและแปลงสตริงตัวอักษรหรือตัวแปรให้เป็นการจัดเรียงของฟิลด์โดยอัตโนมัติ เปิดใช้งาน "รวมแผนการดำเนินการตามจริง" (Control-M) จากนั้นดำเนินการต่อไปนี้ (สมมติว่าคุณได้เรียกใช้แบบสอบถามที่แสดงด้านบนแล้ว):
SELECT *
FROM dbo.[CollateTest-SQL_Latin1_General_CP1_CI_AS] ctSQL
WHERE ctSQL.Col1 = N'a';
-- Unspecified collations on string literals and variables assume the database default
-- collation. This mismatch doesn't cause an error because SQL Server adds a
-- "[Col1]=CONVERT_IMPLICIT(nvarchar(4000),[@1],0)" but it can hurt performance.
SELECT *
FROM dbo.[CollateTest-Latin1_General_BIN2] ctWIN
WHERE ctWIN.Col1 = N'a';
-- No CONVERT_IMPLICIT; plan shows "[Col1]=[@1]".
3)และเมื่อพูดถึงการแปลงโดยนัยให้สังเกตว่ามันเป็นตัวอักษรสตริง (ด้วยการเปรียบเทียบโดยนัยของการเปรียบเทียบค่าเริ่มต้นของฐานข้อมูล:) Latin1_General_BIN2
ที่ถูกแปลงไม่ใช่ฟิลด์ในตาราง มีการเดาว่าตัวกรองนี้จะคำนึงถึงขนาดตัวพิมพ์เล็กหรือใหญ่ (การเปรียบเทียบแบบเก่า) หรือแบบตัวพิมพ์เล็กหรือไม่ (การเปรียบเทียบใหม่) รันสิ่งต่อไปนี้เพื่อดู:
INSERT INTO dbo.[CollateTest-SQL_Latin1_General_CP1_CI_AS] (Col1)
VALUES (N'a'), (N'A');
SELECT ctSQL.Col1
FROM dbo.[CollateTest-SQL_Latin1_General_CP1_CI_AS] ctSQL
WHERE ctSQL.Col1 = N'a';
ผลตอบแทน:
Col1
----
a
A
D'โอ้! ไม่เพียง แต่จะมีประสิทธิภาพเล็กน้อย (หรืออาจมีนัยสำคัญมากกว่านี้) สำหรับการค้นหานี้เนื่องจากCONVERT_IMPLICIT()
แต่มันไม่ได้ทำงานในลักษณะที่เป็นตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ที่ต้องการ
ดังนั้นหากการเปรียบเทียบมีการเปลี่ยนแปลงในฐานข้อมูลที่มีตารางอยู่แล้วใช่ทั้งประสิทธิภาพและฟังก์ชั่นจะได้รับผลกระทบ
หากการเปรียบเทียบถูกตั้งค่าไว้ในฐานข้อมูลใหม่พอลได้กล่าวไปแล้วโดยอธิบายว่าการเปรียบเทียบแบบไบนารีในขณะที่รวดเร็วอาจไม่เรียงลำดับตามที่เราคาดหวังหรือปรารถนา
ควรสังเกตว่าคุณสามารถระบุการเปรียบเทียบตามเงื่อนไขได้ตลอดเวลา ส่วนคำสั่งCOLLATEสามารถเพิ่มWHERE
เงื่อนไขORDER BY
และสถานที่ส่วนใหญ่ที่ยอมรับสตริง
ตัวอย่างที่ 1 (เงื่อนไข WHERE):
SELECT tmp.col AS [SQL-CaseSensitive]
FROM (VALUES ('a'), ('A'), ('b'), ('B')) tmp(col)
WHERE tmp.col > 'a' COLLATE SQL_Latin1_General_CP1_CS_AS;
SELECT tmp.col AS [Windows-CaseSensitive]
FROM (VALUES ('a'), ('A'), ('b'), ('B')) tmp(col)
WHERE tmp.col > 'a' COLLATE Latin1_General_CS_AI;
ผลตอบแทน:
SQL-CaseSensitive
-----------------
b
B
Windows-CaseSensitive
-----------------
A
b
B
ตัวอย่างที่ 2 (เรียงตาม):
SELECT tmp.col AS [Windows-CaseSensitive]
FROM (VALUES ('a'), ('A'), ('b'), ('B')) tmp(col)
ORDER BY tmp.col COLLATE Latin1_General_CS_AI;
SELECT tmp.col AS [Windows-Binary]
FROM (VALUES ('a'), ('A'), ('b'), ('B')) tmp(col)
ORDER BY tmp.col COLLATE Latin1_General_BIN2;
ผลตอบแทน:
Windows-CaseSensitive
-----------------
a
A
b
B
Windows-Binary
-----------------
A
B
a
b
ตัวอย่างที่ 3 (คำสั่ง IF):
IF ('A' = 'a') SELECT 1 AS [DatabaseDefault-CaseInsensitive?];
-- if the DB is not case-sensitive or binary, returns 1
IF ('A' = 'a' COLLATE Latin1_General_BIN2) SELECT 2 AS [Windows-Binary];
ผลตอบแทน:
DatabaseDefault-CaseInsensitive?
--------------------------------
1
{nothing}
ตัวอย่างที่ 4 (เชื่อมโยงกับพารามิเตอร์อินพุตของฟังก์ชัน):
SELECT UNICODE(N'🂡') AS [UCS-2],
UNICODE(N'🂡' COLLATE Latin1_General_100_CI_AS_SC) AS [UTF-16];
-- This character is a Unicode supplemental character and is not part of the
-- default UCS-2 encoding. In order for built-in functions to handle these
-- characters correctly, either the DB default collation needs to end in
-- "_SC" (available as of SQL Server 2012), or use as shown here.
-- See the character in more detail here: http://unicode-table.com/en/1F0A1/
ผลตอบแทน:
UCS-2 UTF-16
------ -------
55356 127137
ค่า UCS-2 ที่ 55,356 นั้นถูกต้องบางส่วนซึ่งเป็นค่าแรกของสองค่าใน "คู่ตัวแทน" แต่หากไม่ได้รับการ_SC
เปรียบเทียบอย่างชัดเจนUNICODE()
ฟังก์ชันสามารถดูอักขระแต่ละตัวเป็นค่าไบต์คู่เท่านั้นและไม่ทราบวิธีจัดการคู่ตัวแทนดับเบิลไบต์คู่อย่างถูกต้อง
UPDATE
แม้จะมีตัวอย่างทั้งหมดข้างต้นแง่มุมหนึ่งของการเปรียบเทียบ Case Sensitive ที่มักถูกมองข้ามและถูกทำให้ไร้ผลโดยการเปรียบเทียบ / การเปรียบเทียบแบบไบนารีเป็นการทำให้เป็นมาตรฐาน (องค์ประกอบและการสลายตัว) ซึ่งเป็นส่วนหนึ่งของ Unicode
ตัวอย่างที่ 5 (เมื่อการเปรียบเทียบแบบไบนารีไม่ใช่คำนึงถึงขนาดตัวพิมพ์):
การเปรียบเทียบแบบตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก - เล็กช่วยให้สามารถรวมอักขระที่รวมกับอักขระอื่นเข้าด้วยกันโดยสร้างอักขระอื่นที่มีอยู่แล้วเป็นจุดรหัส Unicode อื่น การเปรียบเทียบแบบตัวพิมพ์เล็ก - ใหญ่ต้องคำนึงถึงอักขระที่แสดงได้ไม่ใช่จุดรหัสที่ใช้ในการสร้าง
SELECT 'Equal' AS [Binary],
NCHAR(0x00FC) AS [ü],
N'u' + NCHAR(0x0308) AS [u + combining diaeresis]
WHERE NCHAR(0x00FC) COLLATE Latin1_General_100_BIN2
= N'u' + NCHAR(0x0308) COLLATE Latin1_General_100_BIN2
-- No result as they are a different number of code points,
-- as well as being different code points.
SELECT 'Equal' AS [Case-Sensitive],
NCHAR(0x00FC) AS [ü],
N'u' + NCHAR(0x0308) AS [u + combining diaeresis]
WHERE NCHAR(0x00FC) COLLATE Latin1_General_100_CS_AS -- ü
= N'u' + NCHAR(0x0308) COLLATE Latin1_General_100_CS_AS -- u + combining diaeresis
-- Result set returned, even being a different number of code points AND Accent Sensitive,
-- due to normalization
ผลตอบแทน:
Binary ü u + combining diaeresis
------- --- -------------------------
{nothing}
Case-Sensitive ü u + combining diaeresis
--------------- --- -------------------------
Equal ü ü
การเปรียบเทียบแบบตัวพิมพ์เล็กและใหญ่ให้ตัวอักษรแบบกว้างเพื่อให้เทียบเท่ากับการเทียบเท่าแบบไม่กว้าง
IF (N'sofia' = N'sofia' COLLATE Latin1_General_100_BIN2)
SELECT 'Values are the same' AS [Binary]
ELSE
SELECT 'Values are different' AS [Binary];
IF (N'sofia' = N'sofia' COLLATE Latin1_General_100_CS_AS)
SELECT 'Values are the same' AS [Case-Sensitive]
ELSE
SELECT 'Values are different' AS [Case-Sensitive];
ผลตอบแทน:
Binary
---------------
Values are different
Case-Sensitive
---------------
Values are the same
_BIN
และ_BIN2
) ไม่ได้เป็นตัวพิมพ์เล็กและตัวพิมพ์ใหญ่!