私は、テキストをUCS-2として扱うことは多くの問題を引き起こすとは考えていません。
(AFAIK)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
場合誰がデセレット文字のフォントがインストールされているだけに、ここにあなたの楽しみのために、実際の文字列です:
Original: TEST
.NET Lower: test
DB Lower: test
オクラホマので、読み出し/書き込み文字列としてサロゲートペアとして解釈されるものが含まれていても、nvarcharフィールドへのエンティティ全体で問題や情報の損失は発生しません。今、char列にC#文字列を書くのはどうですか?私は、いくつかの解釈と変換が必要であると考えています。 – Triynko
シングルバイト列には、検索および並べ替え規則を定義するだけでなく、文字は許可されます。列のコードページの値にマップされているUnicodeコードポイントはすべて保持され、残りは破棄されます。 –
破棄されました...または特定のダミーまたは "非文字"バイトに置き換えられましたか? 1バイトのコードページは、非文字のために特定のバイトを予約しますか?ターゲットコードスペースで定義されていないUnicode文字が疑問符に置き換えられていることを示すいくつかの例を見てきましたが、おそらく非文字がどのように表示されるのでしょうか? – Triynko