Trattare alcuni caratteri arabi come identici


10

In arabo abbiamo personaggi come ا (alef) e أ (alef con hamza).

Gli utenti li scrivono in modo intercambiabile e vogliamo cercarli in modo intercambiabile. SQL Server li considera come caratteri separati. Come posso fare in modo che SQL li tratti come lo stesso personaggio?

Ho pensato di sostituire qualsiasi أ (alef con hamza) con ا (alef) al momento dell'inserimento, ma abbiamo molte alternative in lingua araba non solo ا (alef) e أ (alef con hamza).

Ho provato Arabic_CI_ASe Arabic_CI_AIquesto non risolve il problema.

Ecco uno script per rigenerare il 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'ا%';

Il risultato è:

ArabicChars 

احمد

(1 row(s) affected)

Il risultato desiderato sarebbe entrambe le righe che abbiamo inserito.


Nessun problema. Aaron Bertrand ha una bella sceneggiatura che puoi adattare per testare tutte le possibili raccolte. Tuttavia, sospetto che nessuna raccolta considererà questi due personaggi uguali.
Nick Chammas,

ma hai due caratteri diversi nei nomi indicati, almeno in apparenza. E, naturalmente, penso che dovrebbero essere trattati come caratteri diversiا and أ
nuux

3
@NickChammas come hai indovinato SOUNDEX () restituisci 0000 per qualsiasi personaggio arabo
George Botros

1
@NickChammas: qual è il problema allora: il comportamento dell'utente + ipotesi differisce dal comportamento delle regole di confronto più rigoroso.
gbn,

1
@gbn - Dato che si tratta di lettere diverse, direi che il problema è l'educazione dell'utente. Se gli utenti vogliono che le lettere vengano trattate allo stesso modo, specialmente durante una ricerca, allora quella funzionalità deve essere esplicitamente costruita. Non è un problema di confronto.
Nick Chammas

Risposte:


4

ho fatto alcuni test e immagino che sia una soluzione ma riesco a fare il tuo lavoro, dato che SQL da solo non aiuta molto.

se noti che gli unicodi di questi personaggi sono vicini l'uno all'altro

select unicode(N'أ')
  = 1571

select unicode(N'ا')
  = 1575

select unicode(N'إ')
  = 1573

quindi tra أ e ا, è dal 1571 al 1575 o se vuoi assicurarti di avere tutto in mezzo

assicurati di includere dal 1569 al 1575

quali sono

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

Quindi, per essere sicuro di includere ogni cosa simile nella tua ricerca, puoi usare espressioni regolari

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

quindi in questo caso ottieni tutti i personaggi tra ء e ا che includono tutti quelli tra il 1569 e il 1575

quindi in questo caso se il tuo tavolo ha

 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 query sopra li otterrà tutti.

ma noterai qualcosa di divertente

se hai la tua colonna come chiave primaria

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

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

non sarai in grado di inserire questi 2 record

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

perché ء, أ, إ sono tutti in SQL fanno parte di hamza che è ء

Quindi, se si esegue la query

SELECT * 
FROM TestTable 
WHERE ArabicChars like 'ء%'

ti mostrerà

أحمد
إحمد

quindi per farla breve

a SQL أ non è = to ا perché le sue 2 diverse lettere hamza e alefp

ma ء = آ = أ = ؤ = إ = ئ

sono tutti Hamza ء


Ottimo lavoro @AmmarR
George Botros,

1

questo è uno dei problemi più complicati che ho attraversato

quindi ti scriverò tutto quello che ho provato che non ha funzionato, potrebbe essere che tu possa iniziare dopo

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

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

ho creato la tua colonna usando COLLATE Arabic_CI_AI dove CI = insensibile alle maiuscole e minuscole e AI = accento insensibile, ed è qui che dovrebbe funzionare perché se scegli un'altra lingua come ad esempio S e Š, funziona

ho anche provato a cambiare le regole di confronto del database in Arabic_CI_AI ancora non ha funzionato

puoi anche fascicolare lo script come

SELEZIONA * DA Tabella di test DOVE ArabicChars COLLATE Arabic_CI_AI come 'ا%' COLLATE Arabic_CI_AI;

e ancora non ha funzionato

leggi questo articolo parla dello stesso problema ma dal punto di ordinamento

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

questo è tratto dall'articolo

Ad esempio, un ordinamento definisce se il carattere arabo '' è minore di, uguale a o maggiore di ''. Definisce inoltre se le regole di confronto sono sensibili all'accento (ad esempio, se "" è uguale o non uguale a "").

ecco un'altra persona che ha studiato questo problema ma non è riuscita a trovare alcuna soluzione http://www.siao2.com/2008/11/11/9056745.aspx

cercare di ignorare i segni diacritici o hamza credo che al momento non sia possibile nel server sql

potrebbero essere versioni future


Good Work @AmmarR
George Botros,

0

Per lo scopo menzionato in questo post, è possibile utilizzare solo: SQL_Latin1_General_CP1251_CI_AS [funziona per i set di caratteri arabo e persiano, nonché inglese / latino].

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.