Ignora gli accenti in "dove"


17

Nel nostro database abbiamo più voci con caron / hatschek. Ora i nostri utenti vogliono trovare voci tra cui caron / hatschek quando cercano voci senza. Lo mostrerò con un semplice esempio:

Nel nostro database abbiamo la voce (contatto con il nome)

Millière

quindi questo nome è corretto nel paese in cui vive la persona.

Nel nostro paese non abbiamo personaggi con caron / hatschek, quindi il nostro utente cerca Milliere. Nessun risultato, comeè che ovviamente non corrisponde e.

Non ho idea di come questo potrebbe essere realizzato come é, è,ê e molti altri sono disponibili (e questo è solo un esempio per lettera e...).

(L'altro modo sarebbe molto più semplice, poiché potrei semplicemente sostituire tutte le lettere con caron / hatschek con quella di base. Ovviamente, i nostri utenti vogliono la versione corretta del nome nel database, non quella paralizzata.)


Nota che la lettera "è" non ha un caron / hacek, ha un accento grave; un caron / hacek sarebbe "ě". Intendi "personaggi con accenti" o qualcosa del genere? O intendi in particolare l'accento caron / hacek?
psmears,

intendo qualsiasi personaggio con "segni" (scusate non conosco il nome reale per esso.
lumo

Risposte:


31

Questo problema può essere risolto utilizzando regole di confronto insensibili all'accento .

Il tuo database sta probabilmente utilizzando un confronto AS (Accent Sensitive), quindi per impostazione predefinita cercherà la corrispondenza esatta, inclusi gli accenti.

È possibile indicare alla clausola WHERE di utilizzare un altro confronto rispetto all'impostazione predefinita del database specificando un confronto con il confronto.

In questo dbfiddle ho creato un esempio usando le regole di confronto LATIN1 ma potresti usare lo stesso approccio con le regole di confronto che stai utilizzando semplicemente cambiando AS in AI per le regole di confronto attualmente utilizzate dalla tua colonna.

Utilizzare le regole di confronto insensibili all'accento che corrispondono alle regole di confronto utilizzate dalla colonna. Ad esempio, se la colonna sta usando SQL_Latin1_General_CP1_CI_AS, usa SQL_Latin1_General_CP1_CI_AIe non Latin1_General_CI_ASo Latin1_General_100_CI_ASo nessuna delle varianti di quei due poiché il comportamento delle regole di confronto non SQL_ differirà in più modi rispetto alla semplice insensibilità all'accento e ciò potrebbe non essere previsto dagli utenti.

Puoi controllare le regole di confronto correnti in 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

Leggi tramite Utilizzo delle regole di confronto di SQL Server per ulteriori informazioni.

Quindi, probabilmente vorrai che l'ordinamento utilizzi questa raccolta (come notato da peufeu nei commenti) per assicurarti che "é" sia ordinato con "e". Altrimenti, qualcuno che impagina i risultati in ordine alfabetico sarebbe sorpreso di non trovare "é" dove si aspettano che si trovino, ma se vuoi solo toccare questa query puoi aggiungere anche la COLLATEclausola ORDER BY.

Come osservato da Solomon Rutzky nei commenti, se ciò riguarda solo 1 o alcune colonne, un'altra opzione è quella di creare una colonna calcolata non persistente che semplicemente ripete la colonna "nome" e fornisca l'accento insensibile fascicolazione, quindi indicizza il calcolo colonna. Ciò evita la scansione causata dalla modifica delle regole di confronto all'interno della query. Quindi la query deve filtrare sulla nuova colonna.

Qualcosa di simile a:

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

Oppure potresti anche creare una vista invece di aggiungere una colonna calcolata (come preferisce jyao ).


1
Tom: Vorrei notare (ed evidenziare) che dovrebbero usare la versione insensibile all'accento delle regole di confronto utilizzate dalla colonna (le regole di confronto predefinite del database, menzionate nel paragrafo 3, non sono pertinenti a questa domanda). Se la colonna sta usando SQL_Latin1_General_CP1_CI_AS, usa SQL_Latin1_General_CP1_CI_AIe non Latin1_General_CI_ASo Latin1_General_100_CI_ASo nessuna delle variazioni di quei due poiché il comportamento delle non- SQL_collazioni differirà in più modi rispetto alla semplice insensibilità all'accento, e ciò potrebbe non essere previsto dagli utenti. La collazione si trova in sys.columns.
Solomon Rutzky,

@SolomonRutzky buon suggerimento
Tom V - Team Monica
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.