Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL Server – Definieren einer Spalte vom Typ XML mit UTF-8-Codierung

Gibt es eine Möglichkeit, eine SQL Server-Spalte/-Feld mit UTF-8-Codierung zu definieren?

Nein, die einzige Unicode-Codierung in SQL Server ist UTF-16 Little Endian, also NCHAR , NVARCHAR , NTEXT (seit SQL Server 2005 veraltet, verwenden Sie dies also nicht in der Neuentwicklung; außerdem ist es im Vergleich zu NVARCHAR(MAX) scheiße sowieso) und XML Datentypen behandelt werden. Sie haben keine Auswahl an Unicode-Kodierungen, wie es einige andere RDBMS zulassen.

Sie können UTF-8-codiertes XML in SQL Server einfügen, vorausgesetzt, Sie befolgen diese drei Regeln:

  1. Der eingehende String muss vom Datentyp VARCHAR sein , nicht NVARCHAR (als NVARCHAR ist immer UTF-16 Little Endian, daher der Fehler, dass die Kodierung nicht umgeschaltet werden kann).
  2. Das XML hat eine XML-Deklaration, die ausdrücklich besagt, dass die Kodierung des XML tatsächlich UTF-8 ist:<?xml version="1.0" encoding="UTF-8" ?> .
  3. Die Byte-Sequenz muss die tatsächlichen UTF-8-Bytes sein.

Beispielsweise können wir ein UTF-8-codiertes XML-Dokument importieren, das das Emoji mit dem schreienden Gesicht enthält (und wir können die UTF-8-Bytesequenz für dieses ergänzende Zeichen abrufen, indem wir diesem Link folgen):

SET NOCOUNT ON;
DECLARE @XML XML = '<?xml version="1.0" encoding="utf-8"?><root><test>'
                    + CHAR(0xF0) + CHAR(0x9F) + CHAR(0x98) + CHAR(0xB1)
                    + '</test></root>';

SELECT @XML;
PRINT CONVERT(NVARCHAR(MAX), @XML);

Rückgaben (sowohl auf den Registerkarten „Ergebnisse“ als auch „Nachrichten“):

<root><test>😱</test></root>

Sie erwähnten in einem Kommentar zu @Shnugos Antwort:

Ich hatte keine Probleme beim Einfügen von utf-8-codierten Streams mit utf-8-Header in die NVARCHAR-Spalte von SQL Server 2013. Gibt es ein verstecktes Problem?

Nein, Sie haben nichts UTF-8-kodiert in einem NVARCHAR gespeichert Spalte (außerdem gibt es keine 2013er Version von SQL Server, aber das ist wahrscheinlich nur ein Tippfehler). NVARCHAR ist immer nur UTF-16 Little Endian. Höchstwahrscheinlich wurde Ihr UTF-8-Stream während der Übertragung in SQL Server vom Datenbanktreiber in UTF-16 LE konvertiert. Dies ist die gleiche Codierung, die eine XML-Spalte verwenden würde, aber die XML-Spalte hätte versucht, den Stream von UTF-8 in UTF-16 zu konvertieren, ist jedoch fehlgeschlagen, da es sich bereits um UTF-16 handelt. Das bedeutet auch, dass auf dem Weg aus dem SQL Server das XML-Dokument im NVARCHAR gespeichert wird -Spalte hätte immer noch die XML-Deklaration, die besagt, dass die Kodierung UTF-8 ist, aber es ist definitiv nicht UTF-8.

Wenn Sie die Daten unbedingt in UTF-8 benötigen, weil Sie die UTF-16-LE, die aus SQL Server XML kommt, nicht konvertieren möchten oder NVARCHAR in UTF-8, dann haben Sie keine andere Wahl, als die Daten als VARBINARY(MAX) zu speichern .