Обрабатывать некоторые арабские символы как идентичные

10

В арабском языке у нас есть такие символы, как ا (алеф) и أ (алеф с хамзой).

Пользователи пишут их взаимозаменяемо, и мы хотим искать их взаимозаменяемо. SQL Server обрабатывает их как отдельные символы. Как я могу заставить SQL рассматривать их как один и тот же символ?

Я подумал заменить любой أ (алеф с хамзой) на ا (алеф) при вставке, но у нас есть много альтернатив в арабском языке, не только ا (алеф) и أ (алеф с хамза).

Я попробовал Arabic_CI_ASи , Arabic_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)

Желаемым результатом были бы обе строки, которые мы вставили.

Джордж Ботрос
источник
Нет проблем. Аарон Бертран имеет симпатичный маленький сценарий, который вы можете адаптировать для проверки всех возможных сопоставлений. Тем не менее, я подозреваю, что никакие сопоставления не будут считать эти два символа одинаковыми.
Ник Чаммас
но у вас есть два разных символа в названных именах, по крайней мере, на вид. И, конечно, я думаю, что они должны рассматриваться как разные символыا and أ
nuux
3
@NickChammas, как вы уже догадались, SOUNDEX () возвращает 0000 для любого арабского персонажа
Джордж Ботрос
1
@NickChammas: в чем тогда проблема: поведение пользователя + предположение отличается от более строгого поведения сопоставления.
ГБН
1
@gbn - Учитывая, что это разные буквы, я бы сказал, что проблема в обучении пользователей. Если пользователи хотят, чтобы к этим письмам относились одинаково - особенно при поиске, - то эта функциональность должна быть явно построена. Это не проблема сопоставления.
Ник Чаммас

Ответы:

4

Я провел несколько тестов, и я думаю, что это обходной путь, но он может выполнить вашу работу, поскольку сам по себе SQL не очень помогает.

если вы заметили, что юникоды этих символов близки друг к другу

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'ءحمد');

потому что ء, أ, all все для SQL являются частью хамзы, которая является ء

Так что если вы запустите запрос

SELECT * 
FROM TestTable 
WHERE ArabicChars like 'ء%'

это покажет вам

أحمد
إحمد

Короче говоря,

в SQL أ не = в ا, потому что его 2 разные буквы хамза и алеф

но ء = آ = أ = ؤ = إ = ئ

они все хамза ء

AmmarR
источник
Отличная работа @AmmarR
Джордж Ботрос
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 COLLATE Arabic_CI_AI like 'ا%' COLLATE Arabic_CI_AI;

и это все еще не сработало

проверить эту статью говорит о той же проблеме, но с точки зрения сортировки

http://technet.microsoft.com/en-us/library/cc295829(SQL.90).aspx

это взято из статьи

Например, порядок сортировки определяет, является ли арабский символ '' меньше, равен или больше ''. Он также определяет, является ли сопоставление чувствительным к акценту (например, равно ли оно или нет).

вот еще один человек, который исследовал эту проблему, но не смог найти никакого решения http://www.siao2.com/2008/11/11/9056745.aspx

пытаясь игнорировать диакритические знаки или хамза, я думаю, что это невозможно в SQL Server в настоящее время

могут быть будущие версии

AmmarR
источник
Хорошая работа @AmmarR
Джордж Ботрос
0

Для целей, упомянутых в этом посте, вы можете использовать только: SQL_Latin1_General_CP1251_CI_AS [работает для арабского и персидского языков, а также для английских / латинских наборов символов].

user80831
источник