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:
- La stringa in entrata deve essere di tipo dati
VARCHAR
, nonNVARCHAR
(comeNVARCHAR
è sempre UTF-16 Little Endian, da qui l'errore di non poter cambiare la codifica). - L'XML ha una dichiarazione XML che afferma esplicitamente che la codifica dell'XML è effettivamente UTF-8:
<?xml version="1.0" encoding="UTF-8" ?>
. - 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)
.