Problem:
Ursache:Spalte 'Name' hat eine Groß-/Kleinschreibung (CI
) Sortierung.
Lösung:Sie müssen ein CS
verwenden Sortierung:SELECT * FROM fn_helpcollations() WHERE description LIKE N'%case-sensitive%'
.
Hinweis:Es gibt eine Sortierung auf Datenbankebene und eine Sortierung auf Spaltenebene. Und es gibt auch eine Sortierung auf Serverebene.
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
*/
Das einfache Ändern der Datenbanksortierung wird NICHT Ändern Sie die Sortierung für vorhandene Benutzertabellen und -spalten:
Nach Ändern der Datenbanksortierung , lautet die Ausgabe der obigen Abfragen:
/*
DatabaseCollation -- changed
----------------------------
SQL_Latin1_General_CP1_CS_AS
*/
/*
ColumnCollation -- no change
----------------------------
SQL_Latin1_General_CP1_CI_AS
*/
und, wie Sie die Sortierung der Spalte Name
sehen können bleibt CI.
Darüber hinaus wirkt sich das Ändern der Datenbanksortierung nur auf die neu erstellten Tabellen und Spalten aus. Daher könnte das Ändern der Datenbanksortierung zu seltsamen Ergebnissen führen (meiner Meinung nach ), weil einige [N][VAR]CHAR
Spalten werden CI sein und die neuen Spalten werden CS sein.
Ausführliche Lösung #1:Wenn nur einige Abfragen für die Spalte Name
muss CS
sein dann werde ich WHERE
umschreiben Klausel dieser Abfragen also:
SELECT Name
FROM dbo.Table_2
WHERE Name LIKE 'Joe' AND Name LIKE 'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS
Dadurch wird SQL Server geändert, um eine Index Seek
durchzuführen in Spalte Name
(darin befindet sich ein Index auf Spalte Name
). Außerdem enthält der Ausführungsplan eine implizite Konvertierung (siehe Predicate
Eigenschaft für Index Seek
) wegen folgendem Prädikat Name = N'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS
.
Detaillösung #2:wenn alle Abfragen nach Spalte Name
muss CS sein, dann ändere ich die Sortierung nur für die Spalte Name
also:
-- 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'