Ігноруйте акценти в "де"


17

У нашій базі даних є кілька записів з caron / hatschek. Тепер наші користувачі хочуть знайти записи, включаючи caron / hatschek, коли шукають записи без них. Я покажу це на простому прикладі:

У нашій базі даних є запис (контакт з іменем)

Millière

тож ця назва правильна в країні, в якій живе людина.

У нашій країні у нас немає жодних символів з caron / hatschek, тому наш користувач шукає Milliere. Результатів не виходить, як èі очевидно, не відповідає e.

Я поняття не маю , як це може бути реалізовано , як é, è, êі багато іншого доступні (і це тільки приклад для письма e...).

(Інший спосіб був би набагато простішим, оскільки я міг би просто замінити всі букви caron / hatschek на основний. Очевидно, що наші користувачі хочуть, щоб у базі даних була правильна версія імені, а не каліка.)


Зверніть увагу, що літера "è" не має керону / хасека, вона має серйозний наголос; caron / hacek було б "ě". Ви маєте на увазі "персонажі з наголосами" чи щось подібне? Або ви конкретно маєте на увазі акцент карон / хасек?
psmears

я маю на увазі будь-які символи з "знаками" (вибачте, я не знаю фактичної назви для цього.
lumo

Відповіді:


31

Цю проблему можна вирішити за допомогою акцентування нечутливих зіставлень .

Ваша база даних, ймовірно, використовує порівняння AS (Accent Sensitive), тому за замовчуванням вона шукатиме точну відповідність, включаючи акценти.

Ви можете доручити пункт WHERE використовувати інше порівняння, ніж за замовчуванням у базі даних, вказавши порівняння для порівняння.

У цьому dbfiddle я створив приклад, використовуючи зібрання LATIN1, але ви можете використати той самий підхід до порівняння, яке ви використовуєте, просто змінивши AS в AI для порівняння, яке використовує ваш стовпець.

Використовуйте підставку Accent Insensitive, яка відповідає порівнянню, яку використовує Colummn. Наприклад, якщо стовпець використовує SQL_Latin1_General_CP1_CI_AS, використовує, SQL_Latin1_General_CP1_CI_AIа не, Latin1_General_CI_ASабо Latin1_General_100_CI_ASбудь-яку з варіацій цих двох, оскільки поведінка зіставлень, що не належать до SQL_, буде відрізнятися більше способів, ніж просто нечутливість до акцентів, і цього може не очікувати користувачам.

Ви можете перевірити поточне порівняння в 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

Докладнішу інформацію читайте за допомогою зібрань SQL Server .

Потім ви, мабуть, хочете сортувати, щоб використовувати це порівняння (як зауважив peufeu в коментарях), щоб "é" сортувало з "e". В іншому випадку хтось, хто пагінізує результати в алфавітному порядку, буде здивований, що не знайде "é" там, де вони їх очікують, але якщо ви хочете лише торкнутися цього запиту, ви також можете додати цю COLLATEпропозицію ORDER BY.

Як зазначає Соломон Руцький у коментарях, якщо це стосується лише 1 або декількох стовпців, інший варіант - створити непостійний обчислюваний стовпець, який просто повторює стовпчик "ім'я" та забезпечує порівняння нечутливого зіставлення, а потім індексує обчислені стовпчик. Це дозволяє уникнути сканування, викликаного зміною зіставлення в запиті. Тоді запит потрібно відфільтрувати у новому стовпці.

Щось на зразок:

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);

Або ви також можете створити подання замість додавання обчислюваного стовпця (як віддає перевагу jyao ).


1
Том: Я зазначив (і підкреслив), що вони повинні використовувати Accent-Insensitive версію Collation, яку використовує стовпець (зіставлення бази даних за замовчуванням, згадане в пункті 3, не має відношення до цього питання). Якщо стовпець використовує SQL_Latin1_General_CP1_CI_AS, використовує SQL_Latin1_General_CP1_CI_AIта не Latin1_General_CI_ASвикористовує Latin1_General_100_CI_ASабо будь-яку з варіацій цих двох, оскільки поведінка SQL_неспівпадінь буде відрізнятися більше, ніж просто нечутливість до акцентів, і цього люди можуть не очікувати. Збір знайдено в sys.columns.
Соломон Руцький

@SolomonRutzky хороша пропозиція
Том V - Команда Моніки
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.