Problem:
Przyczyna:kolumna „Nazwa” nie uwzględnia wielkości liter (CI
) zestawienie.
Rozwiązanie:musisz użyć CS
collation:SELECT * FROM fn_helpcollations() WHERE description LIKE N'%case-sensitive%'
.
Uwaga:Istnieje sortowanie bazy danych i sortowanie na poziomie kolumny. Jest też sortowanie na poziomie serwera.
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
*/
Po prostu zmiana sortowania bazy danych NIE zmień sortowanie istniejących tabel i kolumn użytkownika:
Po zmianie sortowania bazy danych , wyjściem powyższych zapytań będzie:
/*
DatabaseCollation -- changed
----------------------------
SQL_Latin1_General_CP1_CS_AS
*/
/*
ColumnCollation -- no change
----------------------------
SQL_Latin1_General_CP1_CI_AS
*/
i jak widać zestawienie kolumny Name
pozostaje CI.
Co więcej, zmiana sortowania bazy danych wpłynie tylko na nowo utworzone tabele i kolumny. Dlatego zmiana sortowania bazy danych może generować dziwne wyniki (według mojej opinii ) ponieważ niektóre [N][VAR]CHAR
kolumny to CI, a nowe kolumny to CS.
Szczegółowe rozwiązanie nr 1:jeśli tylko niektóre zapytania dotyczące kolumny Name
musi być CS
wtedy przepiszę WHERE
klauzulę tych zapytań w ten sposób:
SELECT Name
FROM dbo.Table_2
WHERE Name LIKE 'Joe' AND Name LIKE 'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS
Spowoduje to zmianę w SQL Server, aby wykonać Index Seek
w kolumnie Name
(tam jest indeks w kolumnie Name
). Ponadto plan wykonania będzie zawierał niejawną konwersję (zobacz Predicate
właściwość Index Seek
) ze względu na następujący predykat Name = N'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS
.
Szczegółowe rozwiązanie nr 2:jeśli wszystkie zapytania dotyczące kolumny Name
musi być CS to zmienię sortowanie tylko dla kolumny Name
w ten sposób:
-- 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'