将某些阿拉伯字符视为相同


10

在阿拉伯语中,我们有ا(alef)和أ(带有hamza的alef)之类的字符。

用户可以互换地编写它们,而我们想互换地进行搜索。SQL Server将它们视为单独的字符。如何使SQL将它们视为相同字符?

我曾想在插入时用ا(alef)替换所有أ(alef用hamza),但是我们有很多阿拉伯语的替代品,而不仅仅是ا(alef)和أ(带有hamza的alef)。

我尝试过Arabic_CI_ASArabic_CI_AI但这不能解决问题。

这是重新生成问题的脚本:

CREATE TABLE [dbo].[TestTable] (
    [ArabicChars] [nvarchar](50) NOT NULL,

    CONSTRAINT [PK_TestTable] PRIMARY KEY CLUSTERED 
    (
       [ArabicChars] ASC
    )
) ON [PRIMARY];


INSERT INTO TestTable values (N'احمد');
INSERT INTO TestTable values (N'أحمد');

SELECT * 
FROM TestTable 
WHERE ArabicChars like N'ا%';

结果是:

ArabicChars 

احمد

(1 row(s) affected)

期望的结果将是我们插入的两行。


没问题。亚伦·伯特兰德(Aaron Bertrand)有一个不错的小脚本,您可以修改它来测试所有可能的归类。但是,我怀疑没有排序规则会认为这两个字符相同。
Nick Chammas

但您所陈述的名称中有两个不同的字符,外观至少。当然,我认为他们应该为不同的字符来处理ا and أ
nuux

3
您猜到的@NickChammas SOUNDEX()对于任何阿拉伯字符都会返回0000
George Botros 2012年

1
@NickChammas:然后是问题所在:用户行为+假设不同于更严格的整理行为。
gbn 2012年

1
@gbn-鉴于这些字母是不同的,我想说的是用户教育。如果用户希望对这些字母进行同等对待(尤其是在搜索中),则需要明确构建该功能。这不是整理问题。
Nick Chammas 2012年

Answers:


4

我没有做过几次测试,但我想这是可以解决的,但是可以完成您的工作,因为SQL本身并没有太大帮助。

如果您发现这些字符的unicode彼此接近

select unicode(N'أ')
  = 1571

select unicode(N'ا')
  = 1575

select unicode(N'إ')
  = 1573

因此介于أ和ا之间,介于1571年至1575年之间,或者如果您想确保自己介于两者之间

确保包括1569至1575

哪个是

Select NCHAR(1569) = ء
Select NCHAR(1570) = آ
Select NCHAR(1571) = أ
Select NCHAR(1572) = ؤ
Select NCHAR(1573) = إ
Select NCHAR(1574) = ئ 
Select NCHAR(1575) = ا

因此,要确保您在搜索中包含所有类似的内容,可以使用正则表达式

SELECT * 
FROM TestTable 
WHERE ArabicChars like '%[ء-ا]%'

因此,在这种情况下,您会得到ء和ا之间的所有字符,包括1569至1575之间的所有字符

所以在这种情况下,如果您的桌子有

 CREATE TABLE [dbo].[TestTable]  (
    [ArabicChars] [nvarchar](50) COLLATE Arabic_CI_AI NOT NULL,
) 
INSERT INTO TestTable values (N'احمد');
INSERT INTO TestTable values (N'أحمد');
INSERT INTO TestTable values (N'إحمد');

上面的查询将全部获取。

但你会发现一些有趣的事

如果您将列作为主键

CREATE TABLE [dbo].[TestTable]  (
    [ArabicChars] [nvarchar](50) COLLATE Arabic_CI_AI NOT NULL,

    CONSTRAINT [PK_TestTable] PRIMARY KEY CLUSTERED 
    (
       [ArabicChars] ASC
    )
) ON [PRIMARY];

您将无法插入这2条记录

INSERT INTO TestTable values (N'أحمد');
INSERT INTO TestTable values (N'إحمد');
INSERT INTO TestTable values (N'ءحمد');

因为SQL中的ء,أ,إ都是hamza的一部分,即ء

因此,如果您运行查询

SELECT * 
FROM TestTable 
WHERE ArabicChars like 'ء%'

它会告诉你

أحمد
إحمد

简而言之

SQLأ不是=ا,因为它的2个不同字母hamza和alefp

但ء=آ=أ=ؤ=إ=ئ

他们都是Hamza ء


伟大的作品 @AmmarR
George Botros 2012年

1

这是我遇到的最复杂的问题之一

所以我会把所有我尝试过的方法都写给你,也许你可以在那之后开始

 CREATE TABLE [dbo].[TestTable]  (
    [ArabicChars] [nvarchar](50) COLLATE Arabic_CI_AI NOT NULL,

    CONSTRAINT [PK_TestTable] PRIMARY KEY CLUSTERED 
    (
       [ArabicChars] ASC
    )
) ON [PRIMARY];

我使用COLLATE Arabic_CI_AI创建了您的列,其中CI =不区分大小写,AI =不区分重音,这是它应该起作用的地方,因为如果您选择了另一种语言(例如S和Š),则它可以工作

我也尝试将数据库排序规则更改为Arabic_CI_AI仍然无法正常工作

您还可以整理脚本,例如

SELECT * FROM TestTable在何处ArabicChars像'ا%'那样收集Arabic_CI_AI; COLLATE Arabic_CI_AI;

而且还是没用

查看这篇文章,它谈到了相同的问题,但从排序的角度来看

http://technet.microsoft.com/zh-CN/library/cc295829(SQL.90).aspx

这摘自文章

例如,排序顺序定义阿拉伯字符”是小于,等于还是大于”。它还定义排序规则是否对重音敏感(例如,“是否等于”。)

这是研究此问题但找不到任何解决方案的另一个人 http://www.siao2.com/2008/11/11/9056745.aspx

试图忽略变音符号或hamza,我猜目前在SQL Server中不可能

可能是未来版本


好工作 @AmmarR
乔治·

0

出于本文中提到的目的,您只能使用:SQL_Latin1_General_CP1251_CI_AS [它适用于阿拉伯语和波斯语以及英语/拉丁语字符集]。

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.