我不认为将文本视为 UCS-2 会导致很多问题。
大小写转换应该不是问题,因为(AFAIK)在 BMP 之上没有大小写映射(当然,除了恒等映射!),而且,显然,代理字符将映射到自己。
空白所有其他字符只是自找麻烦。实际上,在不考虑字符值的情况下进行此类转换始终是一项危险的活动。我可以看到它通过字符串截断合法地发生。但是,如果结果中出现任何不匹配的代理,这本身并不是一个大问题。任何接收到此类数据并关心这些数据的系统都可能只是用替换字符替换不匹配的代理,如果它根本不费心做任何事情的话。
显然,字符串长度将是字节/2 而不是字符数,但是一旦您开始深入了解 Unicode 代码图表的深度,字符数无论如何都不是一个非常有用的值。例如,由于字符、RTL 语言、方向控制字符、标签和几种空格字符的组合,一旦离开 ASCII 范围,您将不会在等宽显示中获得良好的结果。高代码点将是您遇到的最少的问题。
为了安全起见,您可能应该将楔形文字存储在与考古学家姓名不同的列中。:D
现在用经验数据更新!
我刚刚进行了一个测试,看看案例转换会发生什么。我用大写的英文单词 TEST 创建了一个字符串,第一次是拉丁文,然后是 Deseret 文。我在 .NET 和 SQL Server 中对这个字符串应用了小写转换。
.NET 版本正确地小写了两个脚本中的所有字母。SQL Server 版本仅将拉丁字符小写,而保留 Deseret 字符不变。这符合处理 UTF-16 和 UCS-2 的预期。
using System;
using System.Data.SqlClient;
class Program
{
static void Main(string[] args)
{
string myDeseretText = "TEST\U00010413\U00010407\U0001041D\U00010413";
string dotNetLower = myDeseretText.ToLower();
string dbLower = LowercaseInDb(myDeseretText);
Console.WriteLine(" Original: {0}", DisplayUtf16CodeUnits(myDeseretText));
Console.WriteLine(".NET Lower: {0}", DisplayUtf16CodeUnits(dotNetLower));
Console.WriteLine(" DB Lower: {0}", DisplayUtf16CodeUnits(dbLower));
Console.ReadLine();
}
private static string LowercaseInDb(string value)
{
SqlConnectionStringBuilder connection = new SqlConnectionStringBuilder();
connection.DataSource = "(local)";
connection.IntegratedSecurity = true;
using (SqlConnection conn = new SqlConnection(connection.ToString()))
{
conn.Open();
string commandText = "SELECT LOWER(@myString) as LoweredString";
using (SqlCommand comm = new SqlCommand(commandText, conn))
{
comm.CommandType = System.Data.CommandType.Text;
comm.Parameters.Add("@myString", System.Data.SqlDbType.NVarChar, 100);
comm.Parameters["@myString"].Value = value;
using (SqlDataReader reader = comm.ExecuteReader())
{
reader.Read();
return (string)reader["LoweredString"];
}
}
}
}
private static string DisplayUtf16CodeUnits(string value)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (char c in value)
sb.AppendFormat("{0:X4} ", (int)c);
return sb.ToString();
}
}
输出:
Original: 0054 0045 0053 0054 D801 DC13 D801 DC07 D801 DC1D D801 DC13
.NET Lower: 0074 0065 0073 0074 D801 DC3B D801 DC2F D801 DC45 D801 DC3B
DB Lower: 0074 0065 0073 0074 D801 DC13 D801 DC07 D801 DC1D D801 DC13
以防万一有人安装了 Deseret 字体,以下是供您欣赏的实际字符串:
Original: TEST
.NET Lower: test
DB Lower: test