web-dev-qa-db-fra.com

Ignorez les accents dans «où»

Dans notre base de données, nous avons plusieurs entrées avec caron/hatschek. Maintenant, nos utilisateurs veulent trouver des entrées, y compris caron/hatschek, lorsqu'ils recherchent des entrées sans. Je vais le montrer par un exemple simple:

Dans notre base de données, nous avons l'entrée (contact avec nom)

Millière

donc ce nom est correct dans le pays où la personne vit.

Dans notre pays, nous n'avons aucun caractère avec caron/hatschek, donc notre utilisateur recherche Milliere. Aucun résultat n'apparaît, car è ne correspond évidemment pas à e.

Je ne sais pas comment cela pourrait être réalisé comme é, è, ê et bien d'autres sont disponibles (et ce n'est qu'un exemple pour la lettre e...).

(L'autre façon serait beaucoup plus facile, car je pourrais simplement remplacer toutes les lettres par caron/hatschek par la chaîne de base. Évidemment, nos utilisateurs veulent la bonne version du nom dans la base de données, pas celle qui est paralysée.)

18
lumo

Ce problème peut être résolu en utilisant classements insensibles aux accents .

Votre base de données utilise probablement un classement AS (Accent Sensitive) donc par défaut, il recherchera la correspondance exacte, y compris les accents.

Vous pouvez demander à la clause WHERE d'utiliser un classement différent de celui par défaut de la base de données en spécifiant un classement avec la comparaison.

Dans ce dbfiddle j'ai créé un exemple en utilisant les classements LATIN1 mais vous pouvez utiliser la même approche avec le classement que vous utilisez en changeant simplement AS en AI pour le classement que votre colonne utilise actuellement.

Utilisez le classement Accent Insensitive qui correspond au classement utilisé par la colonne. Par exemple, si la colonne utilise SQL_Latin1_General_CP1_CI_AS, utilisation SQL_Latin1_General_CP1_CI_AI et pas Latin1_General_CI_AS ou Latin1_General_100_CI_AS ou l'une des variantes de ces deux, car le comportement des classements non-SQL_ différera de bien des façons plus que la simple insensibilité à l'accent, et cela pourrait ne pas être attendu par les utilisateurs.

Vous pouvez vérifier le classement actuel dans 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

Lisez tilisation des classements SQL Server pour plus d'informations.

Ensuite, vous voudrez probablement que le tri utilise ce classement (comme peufe noté dans les commentaires) pour vous assurer que "é" trie avec "e". Sinon, quelqu'un qui pagine les résultats dans l'ordre alphabétique serait surpris de ne pas trouver le "é" où il s'attend à ce qu'il se trouve, mais si vous voulez seulement toucher cette requête, vous pouvez ajouter la clause COLLATE à la ORDER BY aussi.

Comme indiqué par Solomon Rutzky dans les commentaires, si cela n'affecte que 1 ou quelques colonnes, une autre option consiste à créer une colonne calculée non persistante qui répète simplement la colonne "nom" et fournit l'accent insensible classement, puis indexez la colonne calculée. Cela évite l'analyse provoquée par la modification du classement dans la requête. Ensuite, la requête doit filtrer sur la nouvelle colonne.

Quelque chose comme:

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

Ou vous pouvez également créer une vue au lieu d'ajouter une colonne calculée (comme jyao préfère).