Проблем:
Причина:Колона „Име“ има регистър без значение (CI
) съпоставяне.
Решение:Трябва да използвате CS
подреждане:SELECT * FROM fn_helpcollations() WHERE description LIKE N'%case-sensitive%'
.
Забележка:Има съпоставяне на база данни и на ниво колона. Освен това има съпоставяне на ниво сървър.
SELECT DATABASEPROPERTYEX(DB_NAME(), 'Collation') AS DatabaseCollation
/*
-- Sample output (my database)
DatabaseCollation
----------------------------
SQL_Latin1_General_CP1_CI_AS
*/
SELECT col.collation_name AS ColumnCollation
FROM sys.columns col
WHERE col.object_id = OBJECT_ID(N'dbo.Table_2')
AND col.name = N'Name'
/*
-- Sample output (my database)
ColumnCollation
----------------------------
SQL_Latin1_General_CP1_CI_AS
*/
Простата промяна на сортирането на базата данни НЯМА променете сортирането за съществуващи потребителски таблици и колони:
След промяна на сортирането на база данни , резултатът от горните заявки ще бъде:
/*
DatabaseCollation -- changed
----------------------------
SQL_Latin1_General_CP1_CS_AS
*/
/*
ColumnCollation -- no change
----------------------------
SQL_Latin1_General_CP1_CI_AS
*/
и както можете да видите сортирането на колона Name
остава CI.
Нещо повече, промяната на сортирането на базата данни ще засегне само новосъздадените таблици и колони. По този начин промяната на сортирането на базата данни може да генерира странни резултати (по мое мнение ), защото някои [N][VAR]CHAR
колоните ще бъдат CI, а новите колони ще бъдат CS.
Подробно решение #1:ако само някои заявки за колона Name
трябва да е CS
тогава ще пренапиша WHERE
клауза на тези заявки по следния начин:
SELECT Name
FROM dbo.Table_2
WHERE Name LIKE 'Joe' AND Name LIKE 'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS
Това ще даде промяна на SQL Server да извърши Index Seek
в колона Name
(има индекс на колона Name
). Освен това планът за изпълнение ще включва имплицитно преобразуване (вижте Predicate
свойство за Index Seek
) поради следния предикат Name = N'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS
.
Подробно решение #2:ако всички заявки за колона Name
трябва да е CS, тогава ще променя сортирането само за колона Name
по този начин:
-- Drop all objects that depends on this column (ex. indexes, constraints, defaults)
DROP INDEX IX_Table_2_Name ON dbo.Table_2
-- Change column's collation
ALTER TABLE dbo.Table_2
ALTER COLUMN Name VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CS_AS
-- Replace VARCHAR(50) with proper data type and max. length
-- Replace COLLATE SQL_Latin1_General_CP1_CS_AS with the right CS collation
-- Recreate all objects that depends on column Name (ex. indexes, constraints, defaults)
CREATE INDEX IX_Table_2_Name ON dbo.Table_2 (Name)
-- Test query
SELECT Name
FROM dbo.Table_2
WHERE Name LIKE 'Joe'