sql >> Database >  >> RDS >> Sqlserver

SQL Server Like Query niet hoofdlettergevoelig

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:

Bron

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'



  1. PostgreSQL-lef:wat is "resjunk"?

  2. Hoe een variabele in te stellen vanuit een SQL-query?

  3. NIET IN vs NIET BESTAAT

  4. SQL-query om schema van alle tabellen te doorzoeken