Tratar certos caracteres árabes como idênticos


10

Em árabe, temos caracteres como ا (alef) e أ (alef com hamza).

Os usuários os escrevem de forma intercambiável e queremos pesquisá-los de forma intercambiável. O SQL Server os trata como caracteres separados. Como posso fazer o SQL tratá-los como o mesmo caractere?

Pensei em substituir qualquer أ (alef com hamza) por ا (alef) na inserção, mas temos muitas alternativas no idioma árabe, não apenas ا (alef) e أ (alef com hamza).

Eu tentei Arabic_CI_ASe Arabic_CI_AImas isso não resolve o problema.

Aqui está um script para regenerar o problema:

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

O resultado é:

ArabicChars 

احمد

(1 row(s) affected)

O resultado desejado seria as duas linhas que inserimos.


Sem problemas. Aaron Bertrand tem um pequeno script que você pode adaptar para testar todos os agrupamentos possíveis. No entanto, suspeito que nenhum agrupamento considerará esses dois caracteres iguais.
Nick Chammas

mas você está tendo dois caracteres diferentes nos nomes declarados, pelo menos na aparência. E, claro, eu acho que eles devem ser tratados como diferentes caracteresا and أ
nuux

3
@NickChammas como você adivinhou SOUNDEX () retorno 0000 para qualquer caractere árabe
George Botros

11
@NickChammas: qual é o problema: o comportamento do usuário + suposição difere do comportamento mais rigoroso de agrupamento.
GBN

11
@gbn - Como essas letras são diferentes, eu diria que o problema é a educação do usuário. Se os usuários desejam que essas letras sejam tratadas igualmente - especialmente em uma pesquisa -, essa funcionalidade precisa ser explicitamente criada. Não é um problema de agrupamento.
31412 Nick Chammas

Respostas:


4

Eu fiz alguns testes e acho que é uma solução alternativa, mas pode fazer seu trabalho, já que o SQL não ajuda muito.

se você perceber que os unicodes desses caracteres estão próximos um do outro

select unicode(N'أ')
  = 1571

select unicode(N'ا')
  = 1575

select unicode(N'إ')
  = 1573

então, entre أ e ا, é de 1571 a 1575 ou se você quiser ter certeza de que tudo fica entre

certifique-se de incluir de 1569 a 1575

que são

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

Portanto, para incluir tudo semelhante em sua pesquisa, você pode usar expressões regulares

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

portanto, nesse caso, você obtém todos os caracteres entre ء e ا, que incluem todos aqueles entre 1569 e 1575

Portanto, neste caso, se sua mesa tiver

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

a consulta acima irá obter todos eles.

mas você notará algo engraçado

se você tiver sua coluna como chave primária

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

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

você não poderá inserir esses 2 registros

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

porque ء, أ, إ são todos para SQL fazem parte do hamza que é ء

Então, se você executar a consulta

SELECT * 
FROM TestTable 
WHERE ArabicChars like 'ء%'

isso vai te mostrar

أحمد
إحمد

Então, para resumir a longa história

para SQL ã não é = para ا porque são 2 letras diferentes hamza e alefp

mas ء = آ = أ = ؤ = إ = ئ

eles são todos Hamza ء


Bom trabalho @AmmarR
George Botros

1

esse é um dos problemas mais complicados pelos quais passei

então eu vou escrever tudo o que eu tentei que não funcionou, pode ser que você possa começar depois disso

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

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

Eu criei sua coluna usando COLLATE Arabic_CI_AI em que CI = insensível a maiúsculas e minúsculas e AI = insensível a sotaque, e é aqui que deve funcionar porque se você escolher outro idioma como, por exemplo, S e Š, ele funcionará

Eu também tentei alterar o agrupamento do banco de dados para Arabic_CI_AI ainda não funcionou

você também pode agrupar o script como

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

e ainda não funcionou

confira este artigo que fala sobre o mesmo problema, mas do ponto de classificação

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

isso é retirado do artigo

Por exemplo, uma ordem de classificação define se o caractere árabe '' é menor que, igual a ou maior que ''. Ele também define se o agrupamento é sensível ao acento (por exemplo, se '' é igual ou não a '').

aqui está outra pessoa que pesquisou esse problema, mas não conseguiu encontrar nenhuma solução http://www.siao2.com/2008/11/11/9056745.aspx

tentando ignorar diacríticos ou hamza eu acho que não é possível no servidor sql atualmente

podem ser versões futuras


Bom trabalho @AmmarR
George Botros

0

Para os fins mencionados neste post, você pode usar apenas: SQL_Latin1_General_CP1251_CI_AS [funciona para conjuntos de caracteres em árabe e persa e em inglês / latim].

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.