Existe uma maneira de definir uma coluna/campo do SQL Server como tendo codificação UTF-8?
Não, a única codificação Unicode no SQL Server é UTF-16 Little Endian, que é como o
NCHAR
, NVARCHAR
, NTEXT
(desatualizado a partir do SQL Server 2005, portanto, não use isso em novos desenvolvimentos; além disso, é uma droga em comparação com NVARCHAR(MAX)
mesmo assim) e XML
tipos de dados são tratados. Você não tem a opção de codificações Unicode como alguns outros RDBMS's permitem. Você pode inserir XML codificado em UTF-8 no SQL Server, desde que siga estas três regras:
- A string de entrada deve ser do tipo de dados
VARCHAR
, nãoNVARCHAR
(comoNVARCHAR
é sempre UTF-16 Little Endian, daí o erro de não poder alternar a codificação). - O XML tem uma declaração XML que afirma explicitamente que a codificação do XML é realmente UTF-8:
<?xml version="1.0" encoding="UTF-8" ?>
. - A sequência de bytes precisa ser os bytes UTF-8 reais.
Por exemplo, podemos importar um documento XML codificado em UTF-8 contendo o emoji de rosto gritando (e podemos obter a sequência de bytes UTF-8 para esse caractere suplementar seguindo esse 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);
Retorna (nas guias "Resultados" e "Mensagens"):
<root><test>😱</test></root>
Você mencionou em um comentário na resposta de @Shnugo:
Não tive problemas ao inserir fluxos codificados em utf-8 com cabeçalho utf-8 na coluna NVARCHAR do SQL Server 2013. Haveria um problema oculto?
Não, você não armazenou nada codificado em UTF-8 em um
NVARCHAR
coluna (além disso, não há versão 2013 do SQL Server, mas provavelmente é apenas um erro de digitação). NVARCHAR
é apenas UTF-16 Little Endian. Muito provavelmente seu fluxo UTF-8 foi convertido em UTF-16 LE pelo driver do banco de dados durante o trânsito no SQL Server. Essa é a mesma codificação que uma coluna XML usaria, mas a coluna XML teria tentado converter o fluxo de UTF-8 em UTF-16, mas falhou porque já era UTF-16. Isso também significa que, ao sair do SQL Server, o documento XML armazenado no arquivo NVARCHAR
coluna ainda teria a declaração XML informando que a codificação é UTF-8, mas definitivamente não é UTF-8. Se você absolutamente precisa que os dados sejam UTF-8 na saída porque não deseja converter o UTF-16 LE que sai do SQL Server
XML
ou NVARCHAR
em UTF-8, então você não tem escolha a não ser armazenar os dados como VARBINARY(MAX)
.