忽略“哪里”的口音


17

在我们的数据库中,我们有关于caron / hatschek的多个条目。现在,当我们的用户搜索不带caron / hatschek的条目时,他们希望找到这些条目。我将通过一个简单的示例来说明这一点:

在我们的数据库中,我们有条目(带有姓名的联系方式)

Millière

所以这个名字在这个人居住的国家是正确的。

在我们的国家/地区,caron / hatschek没有任何字符,因此我们的用户搜索Milliere。没有结果,è显然不匹配e

我不知道这到底是怎么实现的éèê还有更多可供选择(而这仅是字母一个例子e......)。

(另一种方法会容易得多,因为我可以简单地将所有字母替换为用caron / hatschek替换为基本字母。显然,我们的用户确实希望数据库中使用正确的名称版本,而不是残缺的名称。)


请注意,字母“è”没有纸香/杂色,但口音很重;一个纸箱/杂货店将是“ě”。您是说“带有重音符号的字符”还是类似的意思?还是您特别是指纸箱/鹰嘴豆的口音?
psmears '17

我的意思是任何带有“符号”的字符(对不起,我不知道它的实际名称
。– lumo

Answers:


31

使用重音不敏感归类可以解决此问题。

您的数据库可能正在使用AS(敏感口音)归类,因此默认情况下它将搜索包括重音在内的精确匹配项。

通过指定带有比较的排序规则,可以指示WHERE子句使用数据库默认值以外的其他排序规则。

此dbfiddle中,我创建了一个使用LATIN1归类的示例,但您可以将正在使用的归类使用相同的方法,只需将AS当前更改为AI即可将AI更改为AI。

使用与列使用的排序规则相匹配的重音不敏感排序规则。例如,如果该列正在使用SQL_Latin1_General_CP1_CI_AS,使用SQL_Latin1_General_CP1_CI_AILatin1_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

Solomon Rutzky在评论中所指出的,如果这仅影响1或几列,则另一种选择是创建一个非持久的计算列,该列仅重复“ name”列并提供不区分重音的重音排序,然后对计算出的索引进行索引柱。这样可以避免由于更改查询中的排序规则而导致的扫描。然后,查询需要在新列上进行过滤。

就像是:

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版本(第3段中提到的数据库的默认排序规则与此问题无关)。如果该列正在使用SQL_Latin1_General_CP1_CI_AS,使用SQL_Latin1_General_CP1_CI_AILatin1_General_CI_AS或不使用,或Latin1_General_100_CI_AS这两种方法的任何一种变体,因为非SQL_归类的行为将不仅在不区分重音的方面有更多不同,而且用户可能不会期望这样做。在中找到排序规则sys.columns
所罗门·鲁兹基

@SolomonRutzky的好建议
汤姆五世-莫妮卡团队
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.