Metnin UCS-2 olarak ele alınmasının birçok soruna neden olacağını umuyorum.
Vaka dönüştürmeleri bir sorun olmamalıdır, çünkü (AFAIK) BMP'nin üzerinde (eşlem eşlemesi hariç) hiçbir vaka eşlemesi yoktur ve açıkça, vekil karakterler kendileriyle eşleşeceklerdir.
Diğer tüm karakterleri kapatmak yalnızca sorun çıkarmak içindir. Gerçekte, karakter değerlerini dikkate almadan bu tür dönüşümleri yapmak her zaman tehlikeli bir faaliyettir. Bunu dize kesikleriyle meşru olarak görebiliyorum. Ancak, sonuçta herhangi bir eşleşmemiş vekil görünmüyorsa, bu, büyük sorun değildir. Böyle verileri -veya gözeten- alabilen herhangi bir sistem muhtemelen eşi görülmemiş bir vekil ile yer değiştirecekse, bir ikame karakteri ile değiştirecektir.
Açıkçası, dize uzunluğu, karakter sayısı yerine bayt/2 olacak, ancak Unicode kod çizelgelerinin derinliklerine su eklemeye başladığınızda, karakter sayısı zaten çok kullanışlı bir değer değil. Örneğin, karakterleri, RTL dillerini, yön denetim karakterlerini, etiketleri ve birkaç boşluk karakterini birleştirdiğinizden ASCII aralığından çıktıktan sonra tek aralıklı ekranda iyi sonuçlar almayacaksınız. Yüksek kod noktaları problemlerinizin en azı olacak.
Sadece güvenli tarafta olmak için, çivi yazılı metinleri muhtemelen arkeologların adlarından farklı bir sütunda saklamanız gerekir. : D
Şimdi UPDATE ampirik verilerle!
Sadece durum dönüştürmelerinde neler olduğunu görmek için bir test yaptım. İki kez büyük harfle ingilizce kelime TEST ile bir dizi oluşturdum - önce Latin alfabesinde, sonra Deseret komut dosyasında. .NET ve SQL Server'da bu dizeye küçük harfli bir dönüşüm uyguladım.
.NET sürümü, her iki komut dosyasındaki tüm harfleri doğru bir şekilde küçültüyor. SQL Server sürümü yalnızca Latin karakterlerini indirdi ve Deseret karakterlerini değiştirmedi. Bu, UTF-16 ayetlerinin UCS-2'nin ele alınmasıyla ilgili beklentileri karşılıyor.
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();
}
}
Çıktı:
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
vaka Herkes bir Deseret yazı yüklediği Hemen burada, keyifli zaman gerçek görürsün:
Original: TEST
.NET Lower: test
DB Lower: test
Tamam, okuma/yazma bir dize olarak Bir nvarchar alanına bütün bir varlık, vekil çift olarak yorumlanabilecekleri içeriyor olsa bile, sorunlara veya bilgi kaybına neden olmaz. Şimdi, bir char sütununa C# dizesi yazmaktan ne haber? WOULD'un bazı yorum ve dönüşümleri içerdiğini ve veri kaybına neden olacağından şüpheleniyorum ... – Triynko
Tek baytlık sütunlar, üzerlerinde tanımlanmış Unicode olmayan bir harmanlama dizisine sahiptir, bunlar yalnızca arama ve sıralama kurallarını tanımlamakla kalmaz; karakterlere izin verilir. Sütunun kod sayfasındaki bir değerle eşlenen herhangi bir Unicode kod noktası korunacak ve geri kalanlar atılacaktır. –
Atıldı veya belirli bir kukla veya "karaktersiz" bayt ile değiştirildi mi? Tek baytlık kod sayfaları, karakter olmayanlar için belirli bir bayt ayırır mı? Hedef kod alanında tanımlanmayan Unicode karakterlerinin soru işareti ile değiştirildiğini gösteren bazı örnekler gördüm, ancak belki de karakterlerin nasıl görüntülenmediğini gösteriyor mu? – Triynko