Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

SQL Server Like Query không phân biệt chữ hoa chữ thường

Vấn đề:

Nguyên nhân:Cột 'Tên' không phân biệt chữ hoa chữ thường (CI ) đối chiếu.

Giải pháp:Bạn phải sử dụng CS đối chiếu:SELECT * FROM fn_helpcollations() WHERE description LIKE N'%case-sensitive%' .

Lưu ý:Có một đối chiếu cơ sở dữ liệu và đối chiếu mức cột. Và, cũng có, đối chiếu cấp máy chủ.

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

Chỉ cần thay đổi đối chiếu cơ sở dữ liệu sẽ KHÔNG thay đổi đối chiếu cho các bảng và cột người dùng hiện có:

Nguồn

Sau khi thay đổi đối chiếu cơ sở dữ liệu , đầu ra của các truy vấn trên sẽ là:

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

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

và, như bạn có thể thấy sự đối chiếu của cột Name vẫn là CI.

Hơn nữa, việc thay đổi đối chiếu cơ sở dữ liệu sẽ chỉ ảnh hưởng đến các bảng và cột được tạo mới. Do đó, việc thay đổi đối chiếu cơ sở dữ liệu có thể tạo ra các kết quả lạ (theo ý kiến ​​ của tôi ) vì một số [N][VAR]CHAR các cột sẽ là CI và các cột mới sẽ là CS.

Giải pháp chi tiết # 1:nếu chỉ là một số truy vấn cho cột Name cần phải là CS sau đó tôi sẽ viết lại WHERE do đó, mệnh đề của các truy vấn này:

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

Điều này sẽ cung cấp một thay đổi đối với SQL Server để thực hiện Index Seek trên cột Name (trong đó có một chỉ mục trên cột Name ). Ngoài ra, kế hoạch thực thi sẽ bao gồm một chuyển đổi ngầm định (xem Predicate thuộc tính cho Index Seek ) vì vị từ sau Name = N'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS .

Giải pháp chi tiết # 2:nếu tất cả các truy vấn cho cột Name cần phải là CS thì tôi sẽ chỉ thay đổi đối chiếu cho cột Name do đó:

-- 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. Tách một chuỗi dấu phẩy dài thành bảng mới nhiều cột

  2. Thời gian thu thập cảnh báo đám mây tiêu điểm

  3. CTE để lấy ngày giữa hai ngày bằng SQL Server

  4. Cách chuyển đổi giữa các định dạng ngày trong SQL Server bằng CAST ()

  5. SQL chuyển đổi ngày giờ và trừ giờ