ในเอกสารเกี่ยวกับตัวดำเนินการ LIKEไม่มีอะไรบอกเกี่ยวกับกรณี - ไวของมัน ใช่ไหม? จะเปิด / ปิดได้อย่างไร?
ฉันกำลังสอบถามvarchar(n)
คอลัมน์ในการติดตั้ง Microsoft SQL Server 2005 ถ้าเป็นเรื่องสำคัญ
ในเอกสารเกี่ยวกับตัวดำเนินการ LIKEไม่มีอะไรบอกเกี่ยวกับกรณี - ไวของมัน ใช่ไหม? จะเปิด / ปิดได้อย่างไร?
ฉันกำลังสอบถามvarchar(n)
คอลัมน์ในการติดตั้ง Microsoft SQL Server 2005 ถ้าเป็นเรื่องสำคัญ
คำตอบ:
ไม่ใช่ตัวดำเนินการที่พิจารณาตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ แต่เป็นคอลัมน์เอง
เมื่อทำการติดตั้ง SQL Server การเปรียบเทียบเริ่มต้นจะถูกเลือกให้กับอินสแตนซ์ เว้นแต่จะระบุไว้เป็นอย่างอื่นอย่างชัดเจน (ตรวจสอบ collate clause bellow) เมื่อสร้างฐานข้อมูลใหม่ฐานข้อมูลจะสืบทอดการเปรียบเทียบจากอินสแตนซ์และเมื่อสร้างคอลัมน์ใหม่จะสืบทอดการเรียงลำดับจากฐานข้อมูลที่เป็นเจ้าของ
การเปรียบเทียบเช่นsql_latin1_general_cp1_ci_as
กำหนดวิธีการปฏิบัติต่อเนื้อหาของคอลัมน์ CI ย่อมาจาก case insensitive และ AS ย่อมาจาก accent sensitive
ดูรายการ collations ทั้งหมดได้ที่https://msdn.microsoft.com/en-us/library/ms144250(v=sql.105).aspx
(ก) เพื่อตรวจสอบการเปรียบเทียบอินสแตนซ์
select serverproperty('collation')
(b) เพื่อตรวจสอบการเปรียบเทียบฐานข้อมูล
select databasepropertyex('databasename', 'collation') sqlcollation
(c) เพื่อสร้างฐานข้อมูลโดยใช้การเปรียบเทียบที่แตกต่างกัน
create database exampledatabase
collate sql_latin1_general_cp1_cs_as
(d) เพื่อสร้างคอลัมน์โดยใช้การเปรียบเทียบที่แตกต่างกัน
create table exampletable (
examplecolumn varchar(10) collate sql_latin1_general_cp1_ci_as null
)
(จ) เพื่อแก้ไขการเรียงคอลัมน์
alter table exampletable
alter column examplecolumn varchar(10) collate sql_latin1_general_cp1_ci_as null
เป็นไปได้ที่จะเปลี่ยนอินสแตนซ์และการจัดเรียงฐานข้อมูล แต่จะไม่มีผลกับวัตถุที่สร้างไว้ก่อนหน้า
นอกจากนี้ยังสามารถเปลี่ยนการจัดเรียงคอลัมน์ได้ทันทีสำหรับการเปรียบเทียบสตริง แต่สิ่งนี้ไม่แนะนำอย่างมากในสภาพแวดล้อมการผลิตเนื่องจากมีค่าใช้จ่ายสูงมาก
select
column1 collate sql_latin1_general_cp1_ci_as as column1
from table1
[A-Z]
จะไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่เสมอ [ABCDEFGHIJKLMNOPQRSŠTUVWXYZŽÅÄÖ]
อย่างไรก็ตามดูเหมือนว่าจะเชื่อฟังการเรียงลำดับ
select COLLATION_NAME, iif(cast(COLLATIONPROPERTY(COLLATION_NAME, 'ComparisonStyle') as int) & 1 = 0, 'case sensitive', 'case insensitive') from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'exampletable' and COLUMN_NAME = 'examplecolumn'
การพูดคุยเกี่ยวกับการเรียงลำดับทั้งหมดนี้ดูเหมือนจะซับซ้อนเกินไป ทำไมไม่ใช้สิ่งที่ชอบ:
IF UPPER(@@VERSION) NOT LIKE '%AZURE%'
จากนั้นเช็คของคุณจะไม่คำนึงถึงขนาดตัวพิมพ์
like 'a%'
อาจใช้ดัชนีและupper
เวอร์ชันไม่สามารถทำได้
like
ตัวดำเนินการพิจารณาตัวพิมพ์เล็กและใหญ่หรือไม่
Latin1_General_CI_AS
ว่ากำลังทำUPPER(@@VALUE) NOT LIKE '%SOMETHING%'
หรือ@@COLUMN NOT LIKE '%SOMETHING%'
ไม่เกี่ยวข้อง: ผลลัพธ์จะเหมือนกัน
คุณมีตัวเลือกในการกำหนดลำดับการจัดเรียงในเวลาที่กำหนดตารางของคุณ หากคุณกำหนดลำดับที่คำนึงถึงตัวพิมพ์เล็กและใหญ่LIKE
ตัวดำเนินการของคุณจะทำงานในลักษณะที่คำนึงถึงตัวพิมพ์เล็กและใหญ่ หากคุณกำหนดลำดับการเปรียบเทียบแบบไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่ตัวLIKE
ดำเนินการจะละเว้นตัวพิมพ์เล็กและใหญ่ด้วย:
CREATE TABLE Test (
CI_Str VARCHAR(15) COLLATE Latin1_General_CI_AS -- Case-insensitive
, CS_Str VARCHAR(15) COLLATE Latin1_General_CS_AS -- Case-sensitive
);
นี่คือการสาธิตอย่างรวดเร็วใน sqlfiddleLIKE
แสดงผลของคำสั่งเปรียบเทียบในการค้นหาด้วย
หากคุณต้องการบรรลุการค้นหาที่คำนึงถึงตัวพิมพ์เล็กและใหญ่โดยไม่เปลี่ยนการเรียงของคอลัมน์ / ฐานข้อมูล / เซิร์ฟเวอร์คุณสามารถใช้COLLATE
อนุประโยคได้ตลอดเวลาเช่น
USE tempdb;
GO
CREATE TABLE dbo.foo(bar VARCHAR(32) COLLATE Latin1_General_CS_AS);
GO
INSERT dbo.foo VALUES('John'),('john');
GO
SELECT bar FROM dbo.foo
WHERE bar LIKE 'j%';
-- 1 row
SELECT bar FROM dbo.foo
WHERE bar COLLATE Latin1_General_CI_AS LIKE 'j%';
-- 2 rows
GO
DROP TABLE dbo.foo;
ทำงานในทางอื่นเช่นกันหากคอลัมน์ / ฐานข้อมูล / เซิร์ฟเวอร์ของคุณมีความละเอียดอ่อนและคุณไม่ต้องการการค้นหาที่ละเอียดอ่อนเช่น
USE tempdb;
GO
CREATE TABLE dbo.foo(bar VARCHAR(32) COLLATE Latin1_General_CI_AS);
GO
INSERT dbo.foo VALUES('John'),('john');
GO
SELECT bar FROM dbo.foo
WHERE bar LIKE 'j%';
-- 2 rows
SELECT bar FROM dbo.foo
WHERE bar COLLATE Latin1_General_CS_AS LIKE 'j%';
-- 1 row
GO
DROP TABLE dbo.foo;
WHERE bar COLLATE Latin1_General_CS_AS LIKE '[j-k]%'
มันจะกลับมาJohn
เป็นเงินทุนในการเปรียบเทียบนี้J
อยู่ระหว่างตัวพิมพ์เล็กและตัวพิมพ์เล็กj
k
มันเหมือนaAbBcC...jJkKlLmM...
ซึ่งไม่ชัดเจน ดูเหมือนว่าLatin1_General_BIN
จะสามารถคาดเดาได้มากขึ้นด้วยการค้นหาช่วงด้วยตัวดำเนินการ LIKE
ตัวlike
ดำเนินการรับสองสตริง สตริงเหล่านี้จะต้องมีการเปรียบเทียบที่เข้ากันได้ซึ่งจะมีการอธิบายที่นี่
ในความคิดของฉันสิ่งต่าง ๆ ก็ซับซ้อน แบบสอบถามต่อไปนี้ส่งกลับข้อผิดพลาดที่แจ้งว่าการเปรียบเทียบเข้ากันไม่ได้:
select *
from INFORMATION_SCHEMA.TABLES
where 'abc' COLLATE SQL_Latin1_General_CP1_CI_AS like 'ABC' COLLATE SQL_Latin1_General_CP1_CS_AS
SQL_Latin1_General_CP1_CI_AS
บนเครื่องสุ่มนี่เปรียบเทียบค่าเริ่มต้นคือ แบบสอบถามต่อไปนี้สำเร็จ แต่ไม่ส่งคืนแถว:
select *
from INFORMATION_SCHEMA.TABLES
where 'abc' like 'ABC' COLLATE SQL_Latin1_General_CP1_CS_AS
ค่า "abc" และ "ABC" ไม่ตรงกันในโลกที่ละเอียดอ่อน
กล่าวอีกนัยหนึ่งมีความแตกต่างระหว่างการไม่มีการเปรียบเทียบและการใช้การเปรียบเทียบเริ่มต้น เมื่อด้านหนึ่งไม่มีการเรียงกันระบบจะ "กำหนด" ให้มีการเปรียบเทียบอย่างชัดเจนจากอีกด้านหนึ่ง
(ผลลัพธ์จะเหมือนกันเมื่อการเปรียบเทียบอย่างชัดเจนอยู่ทางด้านซ้าย)
ลองวิ่ง
SELECT SERVERPROPERTY('COLLATION')
จากนั้นตรวจสอบว่าการเปรียบเทียบของคุณมีความละเอียดอ่อนหรือไม่
คุณสามารถเปลี่ยนการเปรียบเทียบใน Microsoft SQL Server Management studio ได้อย่างง่ายดาย
LIKE
จะพิจารณาตัวพิมพ์เล็กและตัวพิมพ์ใหญ่หากไม่ใช่แสดงว่าLIKE
ไม่ใช่