Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

SQL Server Like Query не е чувствителен към главни и малки букви

Проблем:

Причина:Колона „Име“ има регистър без значение (CI ) съпоставяне.

Решение:Трябва да използвате CS подреждане:SELECT * FROM fn_helpcollations() WHERE description LIKE N'%case-sensitive%' .

Забележка:Има съпоставяне на база данни и на ниво колона. Освен това има съпоставяне на ниво сървър.

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

Простата промяна на сортирането на базата данни НЯМА променете сортирането за съществуващи потребителски таблици и колони:

Източник

След промяна на сортирането на база данни , резултатът от горните заявки ще бъде:

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

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

и както можете да видите сортирането на колона Name остава CI.

Нещо повече, промяната на сортирането на базата данни ще засегне само новосъздадените таблици и колони. По този начин промяната на сортирането на базата данни може да генерира странни резултати (по мое мнение ), защото някои [N][VAR]CHAR колоните ще бъдат CI, а новите колони ще бъдат CS.

Подробно решение #1:ако само някои заявки за колона Name трябва да е CS тогава ще пренапиша WHERE клауза на тези заявки по следния начин:

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

Това ще даде промяна на SQL Server да извърши Index Seek в колона Name (има индекс на колона Name ). Освен това планът за изпълнение ще включва имплицитно преобразуване (вижте Predicate свойство за Index Seek ) поради следния предикат Name = N'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS .

Подробно решение #2:ако всички заявки за колона Name трябва да е CS, тогава ще променя сортирането само за колона Name по този начин:

-- 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. Какво е вътрешното представяне на datetime в sql сървър?

  2. Ускорено възстановяване на база данни в SQL Server 2019

  3. Sql сървърът не актуализира записи

  4. Как да използвам повторно подзаявка в sql?

  5. Грешка при закръгляване на SQL Server, даване на различни стойности