Ignoriere Akzente in 'wo'

17

In unserer Datenbank haben wir mehrere Einträge mit caron / hatschek. Jetzt möchten unsere Benutzer Einträge einschließlich caron / hatschek finden, wenn sie nach Einträgen ohne suchen. Ich zeige dies an einem einfachen Beispiel:

In unserer Datenbank haben wir den Eintrag (Kontakt mit Name)

Millière

Daher ist dieser Name in dem Land, in dem die Person lebt, richtig.

In unserem Land haben wir keine Charaktere mit caron / hatschek, daher suchen unsere Benutzer nach Milliere. Es werden keine Ergebnisse angezeigt, da èdiese offensichtlich nicht übereinstimmen e.

Ich habe keine Ahnung , wie diese als realisiert werden konnte é, è, êund viele mehr zur Verfügung steht (und dies ist nur ein Beispiel für die Buchstaben e...).

(Der andere Weg wäre viel einfacher, da ich einfach alle Buchstaben durch caron / hatschek durch die Grundbuchstaben ersetzen könnte. Natürlich möchten unsere Benutzer die richtige Version des Namens in der Datenbank, nicht die verkrüppelte.)

Lumo
quelle
Beachten Sie, dass der Buchstabe "è" kein Caron / Hacek hat, sondern einen gravierenden Akzent hat. ein caron / hacek wäre "ì". Meinen Sie "Zeichen mit Akzenten" oder so ähnlich? Oder meinst du konkret den Caron / Hacek-Akzent?
Psmears
Ich meine alle Zeichen mit "Zeichen" (sorry, ich weiß nicht den tatsächlichen Namen dafür.
Lumo

Antworten:

31

Dieses Problem kann durch akzentunabhängige Kollatierungen gelöst werden .

Ihre Datenbank verwendet wahrscheinlich eine AS-Kollatierung (Accent Sensitive), sodass standardmäßig nach der genauen Übereinstimmung einschließlich der Akzente gesucht wird.

Sie können die WHERE-Klausel anweisen, eine andere Kollatierung als die Standarddatenbank zu verwenden, indem Sie eine Kollatierung mit dem Vergleich angeben.

In dieser Dbfiddle habe ich ein Beispiel mit den LATIN1- Kollatierungen erstellt. Sie können jedoch denselben Ansatz für die Kollatierung verwenden, die Sie verwenden, indem Sie einfach AS in AI für die Kollatierung ändern, die Ihre Spalte derzeit verwendet.

Verwenden Sie die akzentunempfindliche Kollatierung, die der Kollatierung entspricht, die die Spalte verwendet. Wenn die Spalte beispielsweise verwendet SQL_Latin1_General_CP1_CI_AS, verwendet SQL_Latin1_General_CP1_CI_AIund nicht Latin1_General_CI_ASoder Latin1_General_100_CI_ASeine der Variationen dieser beiden, da sich das Verhalten der Nicht-SQL_-Kollatierungen in mehr als nur der Akzentunempfindlichkeit unterscheidet und dies von Benutzern möglicherweise nicht erwartet wird.

Sie können die aktuelle Kollatierung in überprüfen 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

Weitere Informationen finden Sie unter Verwenden von SQL Server-Kollatierungen .

Andererseits möchten Sie wahrscheinlich, dass die Sortierung diese Kollatierung (wie in den Kommentaren angegeben) verwendet, um sicherzustellen, dass "é" mit "e" sortiert. Andernfalls wäre jemand, der die Ergebnisse in alphabetischer Reihenfolge durchblättert, überrascht, das "é" nicht dort zu finden, wo er es erwartet. Wenn Sie jedoch nur diese Abfrage berühren möchten, können Sie die COLLATEKlausel auch der Abfrage hinzufügen ORDER BY.

Wie von Solomon Rutzky in den Kommentaren festgestellt , besteht eine andere Option darin, eine nicht persistierte berechnete Spalte zu erstellen, die einfach die Spalte "name" wiederholt und die akzentunabhängige Sortierung bereitstellt, und die berechnete dann zu indizieren Säule. Dies vermeidet den Scan, der durch Ändern der Sortierung in der Abfrage verursacht wird. Dann muss die Abfrage nach der neuen Spalte filtern.

Etwas wie:

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

Alternativ können Sie auch eine Ansicht erstellen, anstatt eine berechnete Spalte hinzuzufügen (wie von Jyao bevorzugt).

Tom V - Team Monica
quelle
1
Tom: Ich möchte darauf hinweisen (und hervorheben), dass sie die akzentunabhängige Version der in der Spalte verwendeten Kollatierung verwenden sollten (die in Absatz 3 erwähnte Standardkollatierung der Datenbank ist für diese Frage nicht relevant). Wenn die Spalte verwendet wird SQL_Latin1_General_CP1_CI_AS, verwenden Sie SQL_Latin1_General_CP1_CI_AIund nicht Latin1_General_CI_ASoder Latin1_General_100_CI_ASeine der Variationen dieser beiden, da sich das Verhalten der Nicht- SQL_Kollatierungen in mehr als nur der Akzentunempfindlichkeit unterscheidet und dies von Benutzern möglicherweise nicht erwartet wird. Die Kollatierung befindet sich in sys.columns.
Solomon Rutzky
@SolomonRutzky guter Vorschlag
Tom V - Team Monica