Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

SQL Server Suka Query tidak peka huruf besar-kecil

Masalah:

Penyebab:Kolom 'Nama' memiliki case-insensitive (CI ) susunan.

Solusi:Anda harus menggunakan CS collation:SELECT * FROM fn_helpcollations() WHERE description LIKE N'%case-sensitive%' .

Catatan:Ada pemeriksaan database dan pemeriksaan tingkat kolom. Dan, ada juga, susunan tingkat server.

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

Cukup mengubah susunan basis data TIDAK ubah susunan untuk tabel dan kolom pengguna yang ada:

Sumber

Setelah mengubah susunan basis data , output dari kueri di atas adalah:

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

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

dan, seperti yang Anda lihat, susunan kolom Name tetap CI.

Lebih lanjut, mengubah susunan basis data hanya akan memengaruhi tabel dan kolom yang baru dibuat. Dengan demikian, mengubah susunan basis data dapat menghasilkan hasil yang aneh (menurut opini saya ) karena beberapa [N][VAR]CHAR kolom akan menjadi CI dan kolom baru akan menjadi CS.

Solusi terperinci #1:jika hanya beberapa pertanyaan untuk kolom Name harus CS maka saya akan menulis ulang WHERE klausa kueri ini sebagai berikut:

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

Ini akan memberikan perubahan pada SQL Server untuk melakukan Index Seek pada kolom Name (di dalam ada indeks pada kolom Name ). Selain itu, rencana eksekusi akan menyertakan konversi implisit (lihat Predicate properti untuk Index Seek ) karena predikat berikut Name = N'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS .

Solusi terperinci #2:jika semua kueri untuk kolom Name perlu CS maka saya akan mengubah susunan hanya untuk kolom Name demikian:

-- 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. INSERT INTO SELECT * untuk SQL Server, Tidak mungkin, Apakah saya benar?

  2. Bagaimana cara mengganti karakter kolom pertama dan terakhir di sql server?

  3. Pengambilan sampel acak dari kumpulan data besar

  4. Memutar tabel bersama dengan jumlah nilai kolom saat tipe kolom adalah nvarchar

  5. Tabel Pivot dan Kolom Gabungan