Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

SQL Server - definindo uma coluna de tipo XML com codificação UTF-8


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:
  1. A string de entrada deve ser do tipo de dados VARCHAR , não NVARCHAR (como NVARCHAR é sempre UTF-16 Little Endian, daí o erro de não poder alternar a codificação).
  2. 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" ?> .
  3. 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) .