Existuje způsob, jak definovat sloupec/pole SQL Server jako s kódováním UTF-8?
Ne, jediné kódování Unicode v SQL Server je UTF-16 Little Endian, což je způsob, jakým NCHAR
, NVARCHAR
, NTEXT
(zastaralé od SQL Server 2005, takže to nepoužívejte v novém vývoji; kromě toho je to na hovno ve srovnání s NVARCHAR(MAX)
každopádně) a XML
jsou zpracovávány datové typy. Nemáte na výběr z kódování Unicode, jako to umožňují některé jiné RDBMS.
Do SQL Serveru můžete vložit XML kódovaný UTF-8 za předpokladu, že dodržíte tato tři pravidla:
- Příchozí řetězec musí být datového typu
VARCHAR
, nikoliNVARCHAR
(jakoNVARCHAR
je vždy UTF-16 Little Endian, proto chyba spočívající v nemožnosti přepnout kódování). - XML má deklaraci XML, která výslovně uvádí, že kódování XML je skutečně UTF-8:
<?xml version="1.0" encoding="UTF-8" ?>
. - Posloupnost bajtů musí být skutečnými bajty UTF-8.
Můžeme například importovat dokument XML s kódováním UTF-8 obsahující emotikony křičící tváře (a pomocí tohoto odkazu můžeme získat sekvenci bajtů UTF-8 pro tento doplňkový znak):
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);
Vrací (na kartách „Výsledky“ i „Zprávy“):
<root><test>😱</test></root>
V komentáři k odpovědi @Shnugo jste zmínili:
Neměl jsem žádné problémy s vkládáním streamů kódovaných utf-8 s hlavičkou utf-8 do sloupce NVARCHAR SQL Server 2013. Došlo by ke skrytému problému?
Ne, do NVARCHAR
jste neuložili nic kódovaného UTF-8 sloupec (kromě toho neexistuje verze SQL Serveru 2013, ale to je pravděpodobně jen překlep). NVARCHAR
je pouze UTF-16 Little Endian. S největší pravděpodobností byl váš stream UTF-8 převeden na UTF-16 LE ovladačem databáze během přenosu na SQL Server. Toto je stejné kódování, jaké by použil sloupec XML, ale sloupec XML by se pokusil převést stream z UTF-8 na UTF-16, ale selhal, protože již byl UTF-16. To také znamená, že na cestě ze serveru SQL bude dokument XML uložen v NVARCHAR
sloupec by stále měl deklaraci XML uvádějící, že kódování je UTF-8, ale rozhodně to není UTF-8.
Pokud bezpodmínečně potřebujete, aby data na výstupu byla UTF-8, protože nechcete převádět UTF-16 LE vycházející ze serveru SQL XML
nebo NVARCHAR
do UTF-8, pak nemáte jinou možnost, než uložit data jako VARBINARY(MAX)
.