拉丁文整理中的MS SQL阿拉伯语字母

时间:2017-03-11 14:29:43

标签: sql sql-server arabic collation

我已将阿拉伯数据存储在具有拉丁校对的字段中的MS SQL数据库中。我可以使用旧的SqlDrv32.dll驱动程序和odbc读取它。有没有办法将这些数据转换成具有正确数据的阿拉伯语排序规则?

1 个答案:

答案 0 :(得分:3)

您需要做的是确保使用nvarchar而不是varchar存储您的列。不同的是

  • nvarchar :存储UTF-16(即每个字符2个字节)unicode
  • varchar :存储Ansi(即每个字符1个字节)文本

假设您要存储文本:“مرحبا”

如果您(正确地)将其存储到nvarchar列中,该表将包含“مرحبا”

解决方法

但我认为您无法将数据库更改为正确的列类型,您仍然无法使用varchar,而您只需要使用{ Latin-1排序规则中的{1}}列。

在这种情况下,您需要使用您的编程语言直接将“مرحبا”的字节解释为Latin-1:

varchar

所以为了保存:

  • 以保存Windows 1256文本:| Character | Windows 1256 Hex Code | Windows-1252 | |-----------|-----------------------|--------------| | م | E3 | ã | | ر | D1 | Ñ | | ح | CD | Í | | ب | C8 | È | | ا | C7 | Ç |
  • 您必须将其解释为:مرحبا

当您将其保存到数据库时,它将作为ãÑÍÈÇ存储在varchar Latin-1列中。

然后回读

现在你还需要加载它。这意味着您必须使用字符串:

  

ãÑÍÈÇ

当您假设它是Windows-1252编码时,它是如何显示的,并且假设它是Windows-1256编码的。

但我如何实际转换呢?

我不知道您使用的编程语言,但我们可以假设一种现代语言,它能够将文本转换为编码的字节序列。

最终你的目标是写下:

ãÑÍÈÇ

首先,您必须将dbConnection.ExecuteNonQuery("INSERT INTO Users (Name) VALUES (`مرحبا`)"); 从“مرحبا”转换为Windows-1256编码版本:

string

现在您可以编写SQL语句:

String name = "مرحبا";

//Convert the string into a Windows-1256 encoded byte sequence
Encoding arabic = Encoding.GetEncoding(1256);
byte[] nameAsBytes = arabic.GetBytes(name); //e.g. E3 D1 CD C8 C7

//Convert the byte sequence back to a string, but assume it is Windows-1252
Encoding latin1 = Encoding.GetEncoding(1252);
String latinName = latin1.GetString(nameAsBytes); //e.g. "ãÑÍÈÇ"

现在,当您从数据库中读回值时,它将作为dbConnection.ExecuteNonQuery("INSERT INTO Users (Name) VALUES ('ãÑÍÈÇ')"); 来到您的身边:

string

然后,您必须将该文本(Windows-1252)解释为Windows-1256:

SELECT Name FROM Users

Name
----------
ãÑÍÈÇ

1 row(s) affected

神奇的是假设您的文本是Windows-1252编码。我们可以转换辅助函数来强制文本进出Latin1:

String latinName = reader.GetString("Name"); //"ãÑÍÈÇ"

Encoding latin1 = Encoding.GetEncoding(1252);
byte[] nameAsBytes = latin1.GetBytes(latinName);
Encoding arabic = Encoding.GetEncoding(1256);
String name = arabic.GetString(nameAsBytes);

//name is now مرحب

所以它就像:

String ToLatin1(String s)
{
   //"مرحب" ==> "ãÑÍÈÇ"
   //(1256) ==> (1252)

   Encoding from = Encoding.GetEncoding(1256);
   byte[] hex = from.GetBytes(s);

   Encoding to = Encoding.GetEncoding(1252);
   String result = to.GetString(hex);

   return result;
}

String FromLatin1(String s)
{
   //"ãÑÍÈÇ" ==> "مرحب"
   //1252    ==> 1256

   Encoding from = Encoding.GetEncoding(1252);
   byte[] hex = from.GetBytes(s);

   Encoding to = Encoding.GetEncoding(1256);
   String result = to.GetString(hex);

   return result;
}       

dbConnection.ExecuteNonQuery("INSERT INTO Users(Name) VALUES (@name)",
      ToLatin1("مرحب")
);