Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

SQL Server:definizione di una colonna di tipo XML con codifica UTF-8

Esiste un modo per definire una colonna/campo di SQL Server con codifica UTF-8?

No, l'unica codifica Unicode in SQL Server è UTF-16 Little Endian, che è come il NCHAR , NVARCHAR , NTEXT (obsoleto a partire da SQL Server 2005, quindi non usarlo nel nuovo sviluppo; inoltre, fa schifo rispetto a NVARCHAR(MAX) comunque), e XML i tipi di dati vengono gestiti. Non puoi scegliere tra le codifiche Unicode come consentono altri RDBMS.

È possibile inserire XML con codifica UTF-8 in SQL Server, a condizione di seguire queste tre regole:

  1. La stringa in entrata deve essere di tipo dati VARCHAR , non NVARCHAR (come NVARCHAR è sempre UTF-16 Little Endian, da qui l'errore di non poter cambiare la codifica).
  2. L'XML ha una dichiarazione XML che afferma esplicitamente che la codifica dell'XML è effettivamente UTF-8:<?xml version="1.0" encoding="UTF-8" ?> .
  3. La sequenza di byte deve essere i byte UTF-8 effettivi.

Ad esempio, possiamo importare un documento XML codificato UTF-8 contenente l'emoji della faccia urlante (e possiamo ottenere la sequenza di byte UTF-8 per quel carattere supplementare seguendo quel link):

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);

Resi (in entrambe le schede "Risultati" e "Messaggi"):

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

Hai menzionato in un commento sulla risposta di @Shnugo:

Non ho avuto problemi a inserire flussi codificati utf-8 con intestazione utf-8 nella colonna NVARCHAR di SQL Server 2013. Ci sarebbe un problema nascosto?

No, non hai memorizzato nulla con codifica UTF-8 in un NVARCHAR colonna (inoltre, non esiste una versione 2013 di SQL Server, ma probabilmente è solo un errore di battitura). NVARCHAR è sempre e solo UTF-16 Little Endian. Molto probabilmente il tuo flusso UTF-8 è stato convertito in UTF-16 LE dal driver del database durante il transito in SQL Server. Questa è la stessa codifica che userebbe una colonna XML, ma la colonna XML avrebbe tentato di convertire il flusso da UTF-8 in UTF-16 ma non è riuscito perché era già UTF-16. Ciò significa anche che, uscendo da SQL Server, il documento XML è stato archiviato in NVARCHAR la colonna avrebbe ancora la dichiarazione XML che afferma che la codifica è UTF-8, ma sicuramente non è UTF-8.

Se hai assolutamente bisogno che i dati siano UTF-8 in uscita perché non vuoi convertire UTF-16 LE in uscita da SQL Server XML o NVARCHAR in UTF-8, non hai altra scelta che memorizzare i dati come VARBINARY(MAX) .