Offenbar verwendet SQL Server Unicode UCS-2 , eine 2-Byte-Zeichencodierung mit fester Länge, für nchar/nvarchar
-Felder. In der Zwischenzeit verwendet C # die Unicode-Codierung UTF-16 für seine Strings (Anmerkung: Manche Leute betrachten UCS-2 nicht als Unicode, aber es codiert alle die gleichen Codepunkte wie UTF-16 im Unicode Subset 0-0xFFFF, und soweit es SQL Server betrifft, ist das dem "Unicode" am nächsten, das nativ in Bezug auf Zeichenketten unterstützt wird.)
Während UCS-2 die gleichen grundlegenden Codepunkte wie UTF-16 in der Basic Multilingual Plane (BMP) codiert, reserviert es nicht bestimmte Bitmuster, die UTF-16 für Ersatzpaare verwendet.
Wenn ich eine C # Zeichenkette in ein SQL Server nvarchar
(UCS-2) Feld schreibe und es zurücklese, wird dies immer das gleiche Ergebnis liefern?
Es scheint, dass UTF-16 zwar eine Obermenge von UCS-2 in dem Sinne ist, dass UTF-16 mehr Codepunkte codiert (zB über 0xFFFF), aber tatsächlich eine Untermenge von UCS-2 auf der 2-Byte-Ebene , da es restriktiver ist.
Um meine eigene Frage zu beantworten, vermute ich, dass wenn meine C # Zeichenkette Codepunkte über 0xFFFF (dargestellt durch Zeichenpaare) enthält, diese in der Datenbank gut gespeichert und abgerufen würden, aber wenn ich versuchte, sie in der Datenbank zu manipulieren Datenbank (zB vielleicht TOUPPER aufrufen oder versuchen, jedes andere Zeichen auszublenden), dann könnte ich Probleme bekommen, die Zeichenfolge später anzuzeigen ... es sei denn, SQL Server hat Funktionen, die Ersatzpaare bestätigen und nchar/nvarchar
strings effektiv als UTF- behandeln. 16.
Es ist wirklich alles ein bisschen fudge.
Zuerst die Ähnlichkeiten
nchar
/ nvarchar
/ ntext
" speichern Text als eine Zeichenfolge aus 2-Byte-Zeichen. Es ist nicht wirklich wichtig, was Sie in sie einfügen, bis Sie zum Suchen und Sortieren kommen (dann verwendet es die entsprechende Unicode-Kollatierungssequenz). String
speichert auch Text als eine Zeichenfolge aus 2 Byte Char
s. Es ist auch nicht wirklich wichtig, was Sie hineinlegen, bis Sie suchen und sortieren (dann verwendet es die entsprechenden kulturspezifischen Methoden). Jetzt die Unterschiede
String
konvertiert wird, wird die Zeichenfolge immer als UTF-16 (mit vollständiger Unterstützung für mehrsprachige Ebenen) codiert. Kurz gesagt: Solange Sie sowohl CLR- als auch SQL Server-String-Variablen als ganze Textblöcke behandeln , können Sie frei von einem zum anderen ohne Informationsverlust zuweisen. Das zugrundeliegende Speicherformat ist genau das gleiche, obwohl die oben geschichteten Abstraktionen etwas anders sind.
Ich erwarte nicht, dass die Behandlung des Textes als UCS-2 viele Probleme verursachen würde.
Fallkonvertierungen sollten kein Problem darstellen, da (AFAIK) keine Fallzuordnungen über dem BMP vorhanden sind (mit Ausnahme der Identitätszuordnung, natürlich!), und natürlich werden die Ersatzzeichen sich selbst zuordnen.
Blanking jeder andere Charakter fragt nur nach Ärger. In Wirklichkeit ist das Durchführen dieser Art von Transformationen ohne Berücksichtigung der Zeichenwerte immer eine gefährliche Aktivität. Ich kann sehen, dass es legitim mit String-Kürzungen geschieht. Wenn aber im Ergebnis keine unübertroffenen Surrogate auftauchen, ist das selbst kein großes Problem. Jedes System, das solche Daten - und Sorgen - empfängt, wird wahrscheinlich nur das nicht angepasste Surrogat durch ein Ersatzzeichen ersetzen, wenn es überhaupt etwas dagegen unternimmt.
Offensichtlich wird die Zeichenfolgenlänge Bytes / 2 und nicht die Anzahl der Zeichen sein, aber die Anzahl der Zeichen ist sowieso kein sehr nützlicher Wert, sobald Sie die Tiefe der Unicode-Codediagramme untersuchen. Zum Beispiel werden Sie keine guten Ergebnisse in der monospaced Anzeige erhalten, wenn Sie den ASCII-Bereich verlassen, weil Sie Zeichen, RTL-Sprachen, Richtungssteuerzeichen, Tags und verschiedene Arten von Leerzeichen kombinieren. Die hohen Codepunkte werden die geringsten Ihrer Probleme sein.
Um auf der sicheren Seite zu sein, sollten Sie Ihre Keilschrifttexte wahrscheinlich in einer anderen Spalte speichern als die Namen der Archäologen. : D
UPDATE jetzt mit empirischen Daten!
Ich habe gerade einen Test durchgeführt, um zu sehen, was mit Falltransformationen passiert. Ich habe zweimal hintereinander eine Zeichenfolge mit dem englischen Wort TEST in Großbuchstaben geschrieben, zuerst in lateinischer Schrift, dann in Deseret-Schrift. Ich habe in .NET und SQL Server eine Kleinschreibung auf diese Zeichenfolge angewendet.
In der .NET-Version wurden alle Buchstaben in beiden Skripten korrekt untergeordnet. Die SQL Server-Version enthielt nur die lateinischen Zeichen und ließ die Deseret-Zeichen unverändert. Dies entspricht Erwartungen bezüglich der Handhabung von UTF-16 Versen UCS-2.
%Vor%Ausgabe:
%Vor%Für den Fall, dass jemand eine Deseret-Schriftart installiert hat, finden Sie hier die eigentlichen Zeichenfolgen:
%Vor%Tags und Links sql-server character-encoding utf-16 codepoint ucs2