テキストを UCS-2 として扱うことが多くの問題を引き起こすとは思いません。
(私の知る限り) BMP の上に大文字と小文字のマッピングはなく (もちろん ID マッピングを除いて!)、明らかに、代理文字はそれ自体にマッピングされるため、大文字と小文字の変換は問題になりません。
他のすべての文字を空白にすることは、トラブルを求めているだけです. 実際には、キャラクターの価値を考慮せずにこの種の変換を行うことは、常に危険な行為です。文字列の切り捨てで合法的に起こっていることがわかります。しかし、一致しないサロゲートが結果に現れたとしても、それ自体は大きな問題ではありません。そのようなデータを受信し、気にかけているシステムは、おそらく、一致しないサロゲートを代わりの文字に置き換えるだけです。
明らかに、文字列の長さは文字数ではなくバイト/2 になりますが、Unicode コード チャートの深さを調べ始めると、とにかく文字数はあまり有用な値ではありません。たとえば、文字、RTL 言語、方向制御文字、タグ、およびいくつかの種類のスペース文字の組み合わせにより、ASCII 範囲を離れると等幅表示で良い結果が得られません。高いコードポイントは、問題の中で最も少なくなります。
念のため、楔形文字テキストは考古学者の名前とは別の列に保存する必要があります。:D
経験的データで今すぐ更新してください!
ケース変換で何が起こるかを確認するためのテストを実行しました。英単語 TEST を大文字で 2 回使用した文字列を作成しました。最初はラテン文字、次に 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