Tôi không nghĩ rằng việc xử lý văn bản dưới dạng UCS-2 sẽ gây ra nhiều sự cố.
Chuyển đổi trường hợp không phải là một vấn đề, bởi vì (AFAIK) không có ánh xạ trường hợp nào trên BMP (ngoại trừ ánh xạ danh tính!), Và rõ ràng là các ký tự thay thế sẽ tự ánh xạ.
Tẩy trống mọi nhân vật khác chỉ yêu cầu sự cố. Trong thực tế, việc thực hiện các loại biến đổi này mà không xem xét các giá trị ký tự luôn là một hoạt động nguy hiểm. Tôi có thể thấy nó xảy ra một cách hợp pháp với các chuỗi cắt ngắn. Nhưng nếu bất kỳ đại diện chưa từng có nào xuất hiện trong kết quả, bản thân điều này không phải là vấn đề lớn lớn. Bất kỳ hệ thống nào nhận dữ liệu đó — và quan tâm — có lẽ sẽ chỉ thay thế người đại diện chưa từng có bằng một nhân vật thay thế, nếu nó làm phiền bất cứ điều gì về nó cả. Rõ ràng, độ dài chuỗi sẽ là byte/2 chứ không phải là số ký tự, nhưng số ký tự không phải là một giá trị rất hữu ích, khi bạn bắt đầu sửa ống nước độ sâu của biểu đồ mã Unicode. Ví dụ: bạn sẽ không nhận được kết quả tốt trong hiển thị đơn cách một khi bạn rời khỏi phạm vi ASCII, vì kết hợp các ký tự, ngôn ngữ RTL, ký tự điều khiển hướng, thẻ và một số loại ký tự khoảng trắng. Các điểm mã cao sẽ là ít nhất của các vấn đề của bạn.
Chỉ để an toàn, bạn nên lưu trữ các văn bản cuneiform của bạn trong một cột khác với tên của nhà khảo cổ học. : D
CẬP NHẬT ngay bây giờ với dữ liệu thực nghiệm!
Tôi vừa chạy thử nghiệm để xem điều gì xảy ra với các biến đổi trường hợp. Tôi đã tạo một chuỗi có từ TEST bằng tiếng Anh trong chữ hoa hai lần — đầu tiên bằng chữ Latin, sau đó trong tập lệnh Deseret. Tôi áp dụng một chuyển đổi trường hợp thấp hơn cho chuỗi này trong .NET và trong SQL Server.
Phiên bản .NET đã hạ thấp chính xác tất cả các chữ cái trong cả hai tập lệnh. Phiên bản SQL Server chỉ hạ thấp các ký tự Latinh và để lại các ký tự Deseret không thay đổi. Điều này đáp ứng các kỳ vọng về việc xử lý các câu 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();
}
}
Output:
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
Chỉ trong trường hợp ai đã cài đặt một phông chữ Deseret, đây là những chuỗi thực tế cho mái của bạn:
Original: TEST
.NET Lower: test
DB Lower: test
Ok, vậy đọc/viết một chuỗi như một thực thể toàn bộ đến một trường nvarchar sẽ không gây ra vấn đề hoặc mất thông tin, ngay cả khi nó chứa những gì sẽ được hiểu là cặp thay thế. Bây giờ, những gì về việc viết một chuỗi C# vào một cột char? Tôi nghi ngờ rằng sẽ liên quan đến một số giải thích và chuyển đổi và sẽ gây ra mất dữ liệu ... – Triynko
Các cột một byte có một chuỗi đối chiếu không phải Unicode được xác định trên chúng, không chỉ định nghĩa các quy tắc tìm kiếm và sắp xếp, mà còn là trang mã định nghĩa ký tự được cho phép. Bất kỳ điểm mã Unicode nào được ánh xạ tới một giá trị trong trang mã của cột sẽ được giữ nguyên và phần còn lại sẽ bị hủy bỏ. –
Bị hủy bỏ ... hoặc được thay bằng một ký tự giả hoặc byte "không phải ký tự" cụ thể? Các trang mã byte đơn có dự trữ một byte nhất định cho các ký tự không? Tôi đã thấy một số ví dụ cho thấy rằng các ký tự Unicode không được định nghĩa trong không gian mã đích được thay thế bằng dấu chấm hỏi, nhưng có lẽ đó chỉ là cách các ký tự không được hiển thị? – Triynko