Abaikan aksen di 'di mana'

17

Dalam database kami, kami memiliki banyak entri dengan caron / hatschek. Sekarang pengguna kami ingin menemukan entri termasuk caron / hatschek ketika mereka mencari entri tanpa. Saya akan menunjukkan ini dengan contoh sederhana:

Dalam database kami, kami memiliki entri (kontak dengan nama)

Millière

jadi nama ini benar di negara tempat orang tersebut tinggal.

Di negara kami, kami tidak memiliki karakter dengan caron / hatschek, oleh karena itu pengguna kami mencari Milliere. Tidak ada hasil yang muncul, karena èjelas tidak cocok e.

Saya tidak tahu bagaimana ini bisa direalisasikan sebagai é, è, êdan banyak lagi yang tersedia (dan ini hanya contoh surat e...).

(Cara lain akan jauh lebih mudah, karena saya dapat dengan mudah mengganti semua huruf dengan caron / hatschek dengan yang dasar. Jelas, pengguna kami memang menginginkan versi yang benar dari nama dalam database, bukan yang cacat.)

lumo
sumber
Perhatikan huruf "è" tidak memiliki caron / hacek, ia memiliki aksen kubur; caron / hacek akan menjadi "ě". Apakah maksud Anda "karakter dengan aksen" atau sesuatu seperti itu? Atau maksud Anda aksen caron / hacek secara spesifik?
psmears
maksud saya setiap karakter dengan "tanda" (maaf saya tidak tahu nama sebenarnya untuk itu.
lumo

Jawaban:

31

Masalah ini dapat diatasi dengan menggunakan aksen peka aksen .

Basis data Anda mungkin menggunakan susunan AS (Sensent Sensitive) sehingga secara default akan mencari kecocokan yang tepat termasuk aksen.

Anda bisa menginstruksikan klausa WHERE untuk menggunakan collation lain dari default database dengan menentukan collation dengan perbandingan.

Di dbfiddle ini saya membuat contoh menggunakan collations LATIN1 tetapi Anda bisa menggunakan pendekatan yang sama dengan collation yang Anda gunakan dengan hanya mengubah AS menjadi AI untuk collation yang sedang digunakan kolom Anda.

Gunakan collation Accent Insensitive yang cocok dengan collation yang digunakan colummn. Misalnya jika kolom menggunakan SQL_Latin1_General_CP1_CI_AS, gunakan SQL_Latin1_General_CP1_CI_AIdan tidak Latin1_General_CI_ASatauLatin1_General_100_CI_AS salah satu variasi dari keduanya karena perilaku non-SQL_ collations akan berbeda dalam banyak hal lebih dari sekadar aksen-ketidakpekaan, dan yang mungkin tidak diharapkan oleh pengguna.

Anda dapat memeriksa susunan saat ini di sys.columns.

CREATE TABLE testaccent (name nvarchar(50));
GO
INSERT INTO testaccent (name) VALUES ('Millière') , ('Milliere');
GO
-- returns Miliere
SELECT * FROM testaccent WHERE name = 'Milliere';

-- returns both
SELECT * FROM testaccent WHERE name='Milliere' COLLATE Latin1_General_CI_AI

--only returns Miliere
SELECT * FROM testaccent WHERE name='Milliere' COLLATE Latin1_General_CI_AS

Baca melalui Menggunakan SQL Server Collations untuk informasi lebih lanjut.

Kemudian lagi, Anda mungkin ingin menyortir untuk menggunakan susunan ini (seperti yang dicatat oleh peufeu dalam komentar) untuk memastikan bahwa "é" cocok dengan "e". Jika tidak, seseorang yang membuat paginasi melalui hasil dalam urutan abjad akan terkejut tidak menemukan "é" di mana mereka mengharapkannya, tetapi jika Anda hanya ingin menyentuh kueri ini, Anda dapat menambahkan COLLATEklausa keORDER BY juga.

Seperti dicatat oleh Solomon Rutzky dalam komentar, jika ini hanya mempengaruhi 1 atau beberapa kolom, opsi lain adalah membuat kolom yang dihitung tidak-persisten yang hanya mengulangi kolom "nama" dan memberikan susunan tidak sensitif aksen, dan kemudian mengindeks yang dihitung kolom. Ini menghindari pemindaian yang disebabkan oleh perubahan susunan di dalam kueri. Maka permintaan perlu memfilter pada kolom baru.

Sesuatu seperti:

ALTER TABLE 
dbo.[table_name] ADD [SearchName] datatype_of_name_column 
AS ([Name] COLLATE LATIN1_GENERAL_100_CI_AI)); 

CREATE INDEX [IX_table_name_SearchName] 
ON dbo.[table_name] ([SearchName] ASC);

Atau Anda juga bisa membuat tampilan alih-alih menambahkan kolom yang dihitung (seperti yang dipilih jyao ).

Tom V - Tim Monica
sumber
1
Tom: Saya akan mencatat (dan menyoroti) bahwa mereka harus menggunakan versi Accent-Insensitive dari Collation yang digunakan kolom (susunan default basis data, yang disebutkan dalam paragraf 3, tidak relevan dengan pertanyaan ini). Jika kolom tersebut menggunakan SQL_Latin1_General_CP1_CI_AS, menggunakan , SQL_Latin1_General_CP1_CI_AIdan bukan Latin1_General_CI_ASatau Latin1_General_100_CI_ASatau salah satu variasi dari keduanya karena perilaku non- SQL_koleksi akan berbeda dalam lebih banyak cara daripada hanya ketidakpekaan aksen, dan yang mungkin tidak diharapkan oleh pengguna. Kolasi ditemukan di sys.columns.
Solomon Rutzky
@SolomonRutzky saran yang bagus
Tom V - Team Monica