Traiter certains caractères arabes comme identiques

10

En arabe, nous avons des caractères comme ا (alef) et أ (alef avec hamza).

Les utilisateurs les écrivent de manière interchangeable et nous voulons les rechercher de manière interchangeable. SQL Server les traite comme des caractères distincts. Comment puis-je faire en sorte que SQL les traite comme le même caractère?

J'ai pensé remplacer n'importe quel أ (alef avec hamza) par ا (alef) à l'insertion mais nous avons beaucoup d'alternatives en langue arabe non seulement ا (alef) et أ (alef avec hamza).

J'ai essayé Arabic_CI_ASet Arabic_CI_AIcela ne résout pas le problème.

Voici un script pour régénérer le problème:

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'ا%';

Le résultat est:

ArabicChars 

احمد

(1 row(s) affected)

Le résultat souhaité serait les deux lignes que nous avons insérées.

George Botros
la source
Aucun problème. Aaron Bertrand a un joli petit script que vous pouvez adapter pour tester toutes les collations possibles. Cependant, je suppose qu'aucune collation ne considérera ces deux personnages comme les mêmes.
Nick Chammas
mais vous avez deux caractères différents dans les noms indiqués, au moins en apparence. Et bien sûr, je pense qu'ils devraient être traités comme des caractères différentsا and أ
nuux
3
@NickChammas comme vous l'avez deviné SOUNDEX () retourne 0000 pour tout caractère arabe
George Botros
1
@NickChammas: quel est le problème alors: le comportement + l'hypothèse de l'utilisateur diffère du comportement de classement plus strict.
gbn
1
@gbn - Étant donné qu'il s'agit de lettres différentes, je dirais que le problème est l'éducation des utilisateurs. Si les utilisateurs veulent que ces lettres soient traitées de manière égale - en particulier dans une recherche - alors cette fonctionnalité doit être explicitement construite. Ce n'est pas un problème de classement.
Nick Chammas

Réponses:

4

J'ai fait quelques tests et je suppose que c'est un travail à faire, mais je peux faire votre travail, car SQL lui-même n'aide pas beaucoup.

si vous remarquez que les unicodes de ces caractères sont proches les uns des autres

select unicode(N'أ')
  = 1571

select unicode(N'ا')
  = 1575

select unicode(N'إ')
  = 1573

donc entre أ et ا, c'est de 1571 à 1575 ou si vous voulez vous assurer d'avoir tout entre les deux

assurez-vous d'inclure de 1569 à 1575

qui sont

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

Donc, pour vous assurer d'inclure tout ce qui est similaire dans votre recherche, vous pouvez utiliser des expressions régulières

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

dans ce cas, vous obtenez tous les caractères entre ء et ا qui incluent tous ceux entre 1569 et 1575

dans ce cas, si votre table a

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

la requête ci-dessus les obtiendra tous.

mais vous remarquerez quelque chose de drôle

si vous avez votre colonne comme clé primaire

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

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

vous ne pourrez pas insérer ces 2 enregistrements

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

parce que les ء, أ, إ sont tous en SQL font partie de hamza qui est ء

Donc, si vous exécutez la requête

SELECT * 
FROM TestTable 
WHERE ArabicChars like 'ء%'

ça vous montrera

أحمد
إحمد

donc pour faire court

à SQL أ n'est pas = à ا car ses 2 lettres différentes hamza et alefp

mais ء = آ = أ = ؤ = إ = ئ

ils sont tous Hamza ء

AmmarR
la source
Excellent travail @AmmarR
George Botros
1

c'est l'un des problèmes les plus compliqués que j'ai traversés

donc je vais vous écrire tout ce que j'ai essayé qui n'a pas fonctionné, peut-être que vous pouvez commencer après cela

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

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

j'ai créé votre colonne en utilisant COLLATE Arabic_CI_AI où CI = insensible à la casse et AI = insensible à l'accent, et c'est là que son suppose de fonctionner parce que si vous avez choisi une autre langue comme par exemple S et Š, cela fonctionne

j'ai également essayé de changer le classement de la base de données en Arabic_CI_AI ne fonctionnait toujours pas

vous pouvez également assembler le script comme

SELECT * FROM TestTable WHERE ArabicChars COLLATE Arabic_CI_AI comme 'ا%' COLLATE Arabic_CI_AI;

et ça n'a toujours pas marché

consultez cet article, il parle du même problème, mais du point de tri

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

cela est tiré de l'article

Par exemple, un ordre de tri définit si le caractère arabe «» est inférieur, égal ou supérieur à «». Il définit également si le classement est sensible à l'accent (par exemple, si «» est égal ou n'est pas égal à «»).

voici une autre personne qui a recherché ce problème mais n'a trouvé aucune solution http://www.siao2.com/2008/11/11/9056745.aspx

essayer d'ignorer les signes diacritiques ou hamza je suppose que ce n'est pas possible dans le serveur sql actuellement

peut être des versions futures

AmmarR
la source
Good Work @AmmarR
George Botros
0

Aux fins mentionnées dans cet article, vous ne pouvez utiliser que: SQL_Latin1_General_CP1251_CI_AS [cela fonctionne pour l'arabe et le persan ainsi que pour les jeux de caractères anglais / latin].

user80831
la source