Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

SQL Server Like Query nie uwzględnia wielkości liter

Problem:

Przyczyna:kolumna „Nazwa” nie uwzględnia wielkości liter (CI ) zestawienie.

Rozwiązanie:musisz użyć CS collation:SELECT * FROM fn_helpcollations() WHERE description LIKE N'%case-sensitive%' .

Uwaga:Istnieje sortowanie bazy danych i sortowanie na poziomie kolumny. Jest też sortowanie na poziomie serwera.

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

Po prostu zmiana sortowania bazy danych NIE zmień sortowanie istniejących tabel i kolumn użytkownika:

Źródło

Po zmianie sortowania bazy danych , wyjściem powyższych zapytań będzie:

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

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

i jak widać zestawienie kolumny Name pozostaje CI.

Co więcej, zmiana sortowania bazy danych wpłynie tylko na nowo utworzone tabele i kolumny. Dlatego zmiana sortowania bazy danych może generować dziwne wyniki (według mojej opinii ) ponieważ niektóre [N][VAR]CHAR kolumny to CI, a nowe kolumny to CS.

Szczegółowe rozwiązanie nr 1:jeśli tylko niektóre zapytania dotyczące kolumny Name musi być CS wtedy przepiszę WHERE klauzulę tych zapytań w ten sposób:

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

Spowoduje to zmianę w SQL Server, aby wykonać Index Seek w kolumnie Name (tam jest indeks w kolumnie Name ). Ponadto plan wykonania będzie zawierał niejawną konwersję (zobacz Predicate właściwość Index Seek ) ze względu na następujący predykat Name = N'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS .

Szczegółowe rozwiązanie nr 2:jeśli wszystkie zapytania dotyczące kolumny Name musi być CS to zmienię sortowanie tylko dla kolumny Name w ten sposób:

-- 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. wybrać wszystkie bazy danych w sysobjects, które mają tabelę o nazwie „mytable” niezależnie od schematu?

  2. TSQL porównujący dwa zestawy

  3. Wyzwalacz SQL Server wstawia wartości z nowego wiersza do innej tabeli

  4. SQL Server i luki w kolumnie tożsamości

  5. Instalacja klastra pracy awaryjnej serwera SQL -3