Probleem:
Oorzaak:Kolom 'Naam' heeft een hoofdletterongevoelige (CI
) sortering.
Oplossing:u moet een CS
. gebruiken sortering:SELECT * FROM fn_helpcollations() WHERE description LIKE N'%case-sensitive%'
.
Opmerking:er is een databasesortering en een sortering op kolomniveau. En er is ook een sortering op serverniveau.
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
*/
Het eenvoudig wijzigen van de database-sortering zal NIET verander de sortering voor bestaande gebruikerstabellen en kolommen:
Na het wijzigen van de databasesortering , zal de uitvoer van bovenstaande zoekopdrachten zijn:
/*
DatabaseCollation -- changed
----------------------------
SQL_Latin1_General_CP1_CS_AS
*/
/*
ColumnCollation -- no change
----------------------------
SQL_Latin1_General_CP1_CI_AS
*/
en, zoals je kunt zien, is de sortering van kolom Name
blijft CI.
Meer, het wijzigen van de database-sortering heeft alleen invloed op de nieuw gemaakte tabellen en kolommen. Het wijzigen van de database-sortering kan dus vreemde resultaten opleveren (naar mijn mening ) omdat sommige [N][VAR]CHAR
kolommen zullen CI zijn en de nieuwe kolommen zullen CS zijn.
Gedetailleerde oplossing #1:als slechts enkele vragen voor kolom Name
moet CS
. zijn dan herschrijf ik WHERE
clausule van deze zoekopdrachten dus:
SELECT Name
FROM dbo.Table_2
WHERE Name LIKE 'Joe' AND Name LIKE 'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS
Dit geeft een wijziging aan SQL Server om een Index Seek
. uit te voeren op kolom Name
(er is een index in kolom Name
). Het uitvoeringsplan zal ook een impliciete conversie bevatten (zie Predicate
eigenschap voor Index Seek
) vanwege het volgende predikaat Name = N'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS
.
Gedetailleerde oplossing #2:als alle zoekopdrachten voor kolom Name
moet CS zijn, dan verander ik de sortering alleen voor kolom Name
dus:
-- 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'