sql-server – 忽略’where’中的重音

前端之家收集整理的这篇文章主要介绍了sql-server – 忽略’where’中的重音前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在我们的数据库中,我们有多个caron / hatschek条目.
现在,我们的用户希望在没有搜索条目时找到包括caron / hatschek在内的条目.我将通过一个简单的例子来说明这一点:

在我们的数据库中,我们有条目(与名称联系)

Millière

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

在我们国家,我们没有caron / hatschek的任何角色,因此我们的用户搜索Milliere.没有结果,因为è显然不匹配e.

我不知道如何实现这一点,因为é,è,ê还有更多可用(这只是字母e的一个例子).

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

解决方法

使用 accent insensitive collations可以解决此问题.

您的数据库可能正在使用AS(Accent Sensitive)排序规则,因此默认情况下它会搜索包含重音的完全匹配.

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

this dbfiddle中,我创建了一个使用LATIN1排序规则的示例,但是您可以使用与您正在使用的排序规则相同的方法,只需将AS更改为AI以进行列当前使用的排序规则.

使用与colummn正在使用的排序规则匹配的Accent Insensitive排序规则.例如,如果列使用的是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

阅读Using SQL Server Collations了解更多信息.

然后,您可能希望排序使用此排序规则(如评论中所述的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更喜欢).

猜你在找的MsSQL相关文章