sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server Like Query skelner ikke mellem store og små bogstaver

Problem:

Årsag:Kolonne 'Navn' har en forskel mellem store og små bogstaver (CI ) sortering.

Løsning:Du skal bruge en CS collation:SELECT * FROM fn_helpcollations() WHERE description LIKE N'%case-sensitive%' .

Bemærk:Der er en databasesortering og kolonneniveausortering. Og der er også en sortering på 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
*/

Blot at ændre databasesortering vil IKKE ændre sammenstillingen for eksisterende brugertabeller og kolonner:

Kilde

Efter ændring af databasesortering , vil outputtet af ovenstående forespørgsler være:

/*
DatabaseCollation -- changed
----------------------------
SQL_Latin1_General_CP1_CS_AS
*/

/*
ColumnCollation -- no change
----------------------------
SQL_Latin1_General_CP1_CI_AS
*/

og som du kan se sammenstillingen af ​​kolonne Name forbliver CI.

Mere, ændring af databasesortering vil kun påvirke de nyoprettede tabeller og kolonner. Derfor kan ændring af databasesortering generere mærkelige resultater (efter min mening ), fordi nogle [N][VAR]CHAR kolonner vil være CI, og de nye kolonner vil være CS.

Detaljeret løsning #1:hvis blot nogle forespørgsler til kolonne Name skal være CS så vil jeg omskrive WHERE klausul i disse forespørgsler således:

SELECT  Name 
FROM    dbo.Table_2
WHERE   Name LIKE 'Joe' AND Name LIKE 'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS

Dette vil give en ændring til SQL Server for at udføre en Index Seek på kolonne Name (i der er et indeks på kolonne Name ). Udførelsesplanen vil også inkludere en implicit konvertering (se Predicate egenskab for Index Seek ) på grund af følgende prædikat Name = N'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS .

Detaljeret løsning #2:hvis alle forespørgsler til kolonne Name skal være CS, så vil jeg kun ændre sorteringen for kolonne Name således:

-- 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'



  1. Genstart Mysql af PHP

  2. Sådan finder du de underliggende primære (eller unikke) nøglekolonner fra en Oracle-visning

  3. Hvordan kan jeg definere en type i oracle11g, der refererer til en samling af den type?

  4. ORM-forespørgselsresultater:Arrays vs Result-håndtag pakket ind i Iterator-grænsefladen