SQL Server - Definition einer Spalte vom Typ XML mit UTF-8-Codierung
Die Standard-Kodierung für XML-Typ definierten Feld in einer SQL-Servers ist UTF-16. Ich habe keine Probleme beim einfügen in das Feld mit UTF-16-codiertes XML-streams.
Aber wenn ich versuchte, fügen Sie in das Feld mit UTF-8-codierte XML-stream, der insert-Versuch würde die Fehlermeldung Reaktion
unable to switch encoding
.
FRAGE: gibt es eine Möglichkeit zu definieren, die eine SQL Server-Spalte/Feld als UTF-8-Codierung?
Weitere info
Den Einfüge-Operationen werden durchgeführt unter Verwendung von Spring JDBCTemplate.
Den XML-Strom wurde produziert von JAXB Marshaller set auf UTF-8 oder UTF-16-Codierung.
private String marshall(myDAO myTao, JAXBEncoding jaxbEncoding)
throws JAXBException{
JAXBContext jc = JAXBContext.newInstance(ObjectFactory.class);
m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
if (jaxbEncoding!=null)
m.setProperty(Marshaller.JAXB_ENCODING, jaxbEncoding.toString());
StringWriter strw = new StringWriter();
m.marshal(myTao, strw);
String strw.toString();
}
Wo ...
public enum JAXBEncoding {
UTF8("UTF-8"),
UTF16("UTF-16")
;
private String value;
private JAXBEncoding(String value){
this.value = value;
}
public String toString(){
return this.value;
}
}
InformationsquelleAutor Blessed Geek | 2017-01-05
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nein, nur die Unicode-Kodierung in SQL Server UTF-16 Little-Endian, das ist, wie die
NCHAR
,NVARCHAR
,NTEXT
(veraltet seit SQL Server 2005, also zögern Sie nicht, verwenden Sie diese neue Entwicklung, außer, es saugt im Vergleich zuNVARCHAR(MAX)
sowieso), undXML
Datentypen behandelt werden. Sie erhalten nicht eine Wahl von Unicode-Codierungen wie einige andere RDBMS erlauben.Können Sie die UTF-8-codierte XML-Daten in SQL-Server, vorausgesetzt, Sie befolgen Sie diese drei Regeln:
VARCHAR
, nichtNVARCHAR
(wieNVARCHAR
ist immer UTF-16 Little Endian, daher der Fehler nicht in der Lage, schalten Sie die Codierung).<?xml version="1.0" encoding="UTF-8" ?>
.Können wir zum Beispiel importieren einer UTF-8-codierte XML-Dokument mit der Schreiende Gesicht emoji (und wir können das UTF-8-byte-Sequenz für das Ergänzende Zeichen, indem Sie die folgenden, link):
Gibt (in den beiden "Ergebnisse" und "Nachrichten" - tabs):
Sie erwähnt in einem Kommentar auf @Shnugo Antwort:
Nein, Sie hat nicht speichern in UTF-8 codiert alles in einem
NVARCHAR
Spalte (außer, es gibt keine 2013 version von SQL Server, aber das ist wahrscheinlich nur ein Tippfehler).NVARCHAR
ist immer nur UTF-16 Little Endian. Höchstwahrscheinlich UTF-8 stream haben umgewandelt in UTF-16-LE, die von der Datenbank-Treiber, die während des Transports in SQL Server. Dies ist die gleiche Codierung, die eine XML-Spalte verwenden würde, aber die XML-Spalte versucht hätte zu konvertieren, streamen von UTF-8 in UTF-16 jedoch scheiterte es bereits UTF-16. Dies bedeutet auch, dass auf dem Weg aus SQL Server, XML-Dokument gespeichert in derNVARCHAR
Spalte würden immer noch die XML-Deklaration, die besagt, dass die Kodierung ist UTF-8, aber es ist definitiv nicht UTF-8.Wenn du unbedingt die Daten werden von UTF-8 auf dem Weg nach draußen, weil Sie nicht wollen, zu konvertieren zu UTF-16 LE coming-out von SQL Server
XML
oderNVARCHAR
in UTF-8, dann haben Sie keine Wahl aber um die Daten zu speichern, wieVARBINARY(MAX)
.InformationsquelleAutor Solomon Rutzky
Als Sie herausfand, richtig, XML gespeichert werden, wie
unicode (utf-16)
. Es gibt kein anderes format.Innerhalb von SQL-Server gibt es
VARCHAR(MAX)
fürextended ASCII (1-byte)
undNVARCHAR(MAX)
fürutf-16
. Beide können gegossen werden, um XML direkt (solange der string gültig ist XML). Man muss sich bewusst sein, dassVARCHAR(MAX)
möglicherweise nicht in der Lage, sich mit Sonderzeichen... Also - wenn dies ein Problem - Sie sollten stick mitunicode
sowieso.Das problem tritt auf, wenn die encoding-Deklaration enthalten, die innerhalb
<?xml ...?>
:Dies funktioniert:
Dieser produziert einen Fehler:
Aber so funktioniert es wieder (siehe die führenden
N
vor das string-literal):Fazit
Wenn Sie übergeben Sie die Zeichenfolge 1 byte codiert, aber deklariert als utf-16 (oder Umgekehrt), wirst du in Schwierigkeiten kommen. Am besten ist, übergeben Sie Ihre XML ohne die
<?xml ...?>
-Erklärung.UPDATE
Du vermischt zwei Dinge
Codierung
Aus deinem Kommentar:
Ja, es ist richtig, dass
UTF-8
undUTF-16
sind zwei Arten vonunicode
. Aber es ist nicht richtig zu nennenutf-8
die neue de-facto - standard. Dies hängt stark von Ihren Bedürfnissen. Leben in einem englischsprachigen Land, den Umgang mit plain Latein text spart einige bytes mitUTF-8
. Leben irgendwo weit im Osten wird das aufblasen Ihres Textes unglaublich, wegen der vielen 3-und 4-byte-codes.- Und das ist noch wichtiger in Bezug auf Datenbanken - die Feste Breite ist enorm einfacher zu handhaben. Stell dir vor, ein
WHERE SUBSTRING(SomeUTF8Column,100,1)='A'
. Mitutf-16
kann der Motor cut-byte 200 und 201 ohne zu suchen, mitutf-8
den vollständigen string bis Zeichen 100 müssen analysiert werden, um zu erfahren, wo die 100-Zeichen sitzt eigentlich. Ich würde lieberutf-8
nur in den Fällen, wo die band-Breite oder Speicher-Raum ist ein wichtiger Faktor... SQL Server verwendet eine Feste Breite 1-byte-Codierung und keineutf-8
tatsächlich: erweiterte ASCII-in Kombination mit einer Sortierung.- Und das ist noch wichtiger in Bezug auf die XML - XML nicht gespeichert wie der text, den Sie sehen, sondern als eine Hierarchie-Baum. Können Sie speichern buchstäblich alles, was in
(N)VARCHAR
:Diese funktioniert mit jeder Kombination. Sie können erklären
NVARCHAR
und/oder eineN
vor dem literal. Kein problem wegen der impliziten Konvertierungen.Aber interne
VARCHAR
nicht im Umgang mit höheren Codierungen!. Versuchen Sie dies:Diese arbeiten mit
NVARCHAR
undN'Your string'
nur!XML-Speicherung
Wie gesagt, ist XML nicht gespeichert wie der text, den Sie sehen, aber wie ein Baum. Alles ist auf Leistung optimiert. Daher Feste Breite
UTF-16
. Die xml-Deklaration entfallen in jedem Fall...Das problem tritt auf, wenn Sie übergeben eine Zeichenkette, die physisch codiert, wie
utf-8
aber erklärt als etwas anderes (oder Umgekehrt). Sie können den pass in ein echtesUTF-16
mit einem deklarierten Kodierungutf-16
(gleiche mitutf-8
) ohne Probleme.Fazit
Wenn Sie die geringste chance, 3-oder 4-byte-UTF-8-codes, die man einhalten sollte, um UTF-16.
Nicht downvote, aber deine Antwort ist etwas irreführend, in diesem (1)
varchar
ist nicht "utf-8", es ist für die (single-byte-Zeichen) code-Seite definiert, die für die SQL Server-Instanz. Einige Zeichensätze (z.B., "latin1"), sieht viel wie UTF-8, aber Sie nicht das gleiche und die Fütterung von UTF-8 in einevarchar
Spalte wird wahrscheinlich produzieren einige mojibake (z.B., 'Montrél' anstelle von 'Montréal'). (2) UTF-8 und UTF-16 sind nicht "zwei Arten von unicode -", Sie sind zwei Codierungen von Unicode: die Zeichen (code points) sind die gleichen, es ist Ihre Repräsentation als stream-of-bytes unterscheidet.(Weiter auf den zweiten Punkt, viele Menschen finden, diesem Artikel sehr hilfreich.)
Vielen Dank für den link! Ich lese diesen Artikel mit einer Mischung aus Ahh und Schande 🙂 Wirklich aufschlussreich und sehr gut geschrieben.
Alle Ihre Kommentare zusammen (SQL-Server dient als Puffer nur) könnten Sie die Füllung Ihrer UTF-8-codierte XML-Zeichenfolge in eine Spalte des Typs
VARBINARY(MAX)
. Sie werden nicht in der Lage, etwas zu tun mit dieser auf SQL-Ebene (gut, einige ausgefallene,InformationsquelleAutor Shnugo
Einer 2-Schritt-Werke; erste Verschlüsselung Ihrer UTF-8 zu
text
odervarchar(MAX)
und dann zuxml
.InformationsquelleAutor Klompenrunner
"Typumwandlung String und Binary-Instanzen" - Abschnitt der MSDN-Dokument
Erstellen von Instanzen der XML-Daten
erklärt, wie eingehende XML-Daten interpretiert werden. Im wesentlichen,
wenn der SQL-Server empfängt die XML-Daten als
nvarchar
dann "geht von einem zwei-byte-unicode-Codierung wie UTF-16 oder UCS-2",wenn der SQL-Server empfängt die XML-Daten als
varchar
dann standardmäßig wird es mit dem (single-byte character set) - code der Seite definiert, die für die SQL Server-Instanz,wenn der SQL-Server empfängt die XML-Daten als
varbinary
dann "behandelt, als ein codepoint stream direkt übergeben, um der XML-parser" und "eine Instanz ohne BOM und ohne eine Erklärung der Codierung wird interpretiert als UTF-8".Wenn Ihr marshalling-code spuckt eine Java -
String
an den SQL-Server dann ist es sehr wahrscheinlich, gesendet alsnvarchar
da ein Java -String
ist immer ein Unicode-string. Das würde erklären, warum die SQL Server davon ausgegangen, dass UTF-16-Codierung.Wenn Sie wirklich brauchen zum senden der XML-Daten an den SQL-Server mit UTF-8-Codierung (obwohl ich mir nicht vorstellen kann, warum), dann Ihre marshalling code muss wahrscheinlich produzieren einen Strom von (UTF-8-kodierten) bytes, die gesendet werden, um den SQL-Server als
varbinary
.Ich bin mit sql server als frontend-Puffer für diese nachgeschaltete Verbraucher. Wenn ich hatte, um mehr Zeichen/byte-Verarbeitung in der übertragung der xml-stream, das würde Niederlage der Zweck der mit einem frontend-Puffer.
Wenn Sie nur den SQL Server-Speicher als cache für die XML-Daten werden dann vielleicht Sie nicht wirklich brauchen, um zu speichern der XML-Datei in eine wahre
xml
Spalte; Sie können einfach speichern Sie es als "ready to serve" (d.h., korrekt codiert und entkamen) in einem[n]varchar(max)
Spalte. Siehe "XML-Storage-Optionen" - Abschnitt der das MSDN-Dokument für eine Diskussion darüber, ob eine wahrexml
Spalte bieten einen wirklichen nutzen für Ihren speziellen Anwendungsfall.InformationsquelleAutor Gord Thompson