sql >> Databáze >  >> RDS >> Sqlserver

SQL Server Like Query nerozlišuje velká a malá písmena

Problém:

Příčina:Ve sloupci 'Název' se nerozlišují velká a malá písmena (CI ) řazení.

Řešení:Musíte použít CS řazení:SELECT * FROM fn_helpcollations() WHERE description LIKE N'%case-sensitive%' .

Poznámka:Existuje řazení databáze a řazení na úrovni sloupce. A existuje také řazení na úrovni serveru.

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
*/

Pouhá změna řazení databáze NE změnit řazení pro existující uživatelské tabulky a sloupce:

Zdroj

Po změně řazení databáze , výstup výše uvedených dotazů bude:

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

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

a jak můžete vidět řazení sloupce Name zůstává CI.

Navíc změna řazení databází ovlivní pouze nově vytvořené tabulky a sloupce. Změna řazení databází by tedy mohla generovat podivné výsledky (podle mého názoru ), protože některé [N][VAR]CHAR sloupce budou CI a nové sloupce budou CS.

Podrobné řešení č. 1:pokud jsou jen nějaké dotazy na sloupec Name musí být CS pak přepíšu WHERE klauzule těchto dotazů takto:

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

Tím se SQL Server změní na Index Seek ve sloupci Name (ve sloupci Name je index ). Prováděcí plán bude také zahrnovat implicitní konverzi (viz Predicate vlastnost pro Index Seek ) kvůli následujícímu predikátu Name = N'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS .

Podrobné řešení č. 2:pokud jsou všechny dotazy pro sloupec Name musí být CS, pak změním řazení pouze pro sloupec Name tedy:

-- 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. MySQL:UNIQUE, ale DEFAULT NULL - povoleno vytvořením tabulky. Je povoleno vložit více než 1 NULL. Proč?

  2. Nástroje pro správu SQL Server 2017

  3. mysql unie jiný počet sloupců

  4. START TRANSACTION uvnitř kontextu BEGIN ... END nebo mimo syntaxi a LOOP