No espero que tratar el texto como UCS-2 cause muchos problemas.
Las conversiones de casos no deberían ser un problema, porque (AFAIK) no hay asignaciones de casos por encima del BMP (¡excepto el mapeo de identidad, por supuesto!) Y, obviamente, los personajes sustituidos se asignarán a sí mismos.
La supresión de cualquier otro personaje solo está causando problemas. En realidad, hacer este tipo de transformaciones sin tener en cuenta los valores de los caracteres es siempre una actividad peligrosa. Puedo verlo sucediendo legítimamente con truncamientos de cadena. Pero si aparece algún sustituto sin coincidencia en el resultado, esto en sí mismo no es un gran problema . Cualquier sistema que reciba tales datos, y se preocupe, probablemente simplemente reemplace el sustituto sin igual con un personaje de reemplazo, si se molesta en hacer algo al respecto.
Obviamente, la longitud de la cadena va a ser bytes/2 en lugar de número de caracteres, pero el número de caracteres no es un valor muy útil de todos modos, una vez que empiezas a sondear las profundidades de los gráficos Unicode. Por ejemplo, no obtendrá buenos resultados en la visualización monoespaciada una vez que abandone el rango ASCII, debido a la combinación de caracteres, idiomas RTL, caracteres de control direccional, etiquetas y varios tipos de caracteres espaciales. Los puntos altos de código serán el menor de tus problemas.
Por si fuera poco, probablemente debería guardar sus textos cuneiformes en una columna diferente a los nombres del arqueólogo. : D
¡ACTUALIZACIÓN ahora con datos empíricos!
Acabo de ejecutar una prueba para ver qué pasa con las transformaciones de casos. Creé una cadena con la palabra en inglés TEST en mayúscula dos veces primero en script latino, luego en script Deseret. Apliqué una transformación en minúsculas a esta cadena en .NET y en SQL Server.
La versión .NET encerró correctamente todas las letras en ambos scripts. La versión de SQL Server solo bajaba los caracteres latinos y no cambiaba los caracteres Deseret. Esto cumple con las expectativas con respecto al manejo de UTF-16 versos 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();
}
}
Salida:
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
Sólo en caso de que alguien ha instalado una fuente de Deseret, aquí están las cadenas reales para su disfrute:
Original: TEST
.NET Lower: test
DB Lower: test
Ok, por lo que la lectura/escritura de una cadena como una entidad completa a un campo nvarchar no causará problemas o pérdida de información, incluso si contiene lo que se interpretaría como pares de sustitución. Ahora, ¿qué tal escribir una cadena C# en una columna char? Sospecho que implicaría alguna interpretación y conversión y causaría la pérdida de datos ... – Triynko
Las columnas de un solo byte tienen una secuencia de intercalación no Unicode definida en ellas, que no solo define las reglas de búsqueda y clasificación, sino también la página de códigos que define qué los personajes están permitidos Cualquier punto de código Unicode que esté asignado a un valor en la página de códigos de la columna se conservará y el resto se descartará. –
¿Desechado ... o reemplazado por un dummy en particular o un byte "sin carácter"? ¿Las páginas de códigos de un solo byte reservan un cierto byte para los caracteres que no son? He visto algunos ejemplos que muestran que los caracteres Unicode no definidos en el espacio de código de destino se reemplazan con el signo de interrogación, pero ¿tal vez solo cómo se muestran los caracteres? – Triynko