Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

SQL Server - définition d'une colonne de type XML avec encodage UTF-8

Existe-t-il un moyen de définir une colonne/un champ SQL Server comme ayant un encodage UTF-8 ?

Non, le seul encodage Unicode dans SQL Server est UTF-16 Little Endian, c'est ainsi que le NCHAR , NVARCHAR , NTEXT (obsolète à partir de SQL Server 2005, ne l'utilisez donc pas dans un nouveau développement ; de plus, c'est nul par rapport à NVARCHAR(MAX) de toute façon), et XML les types de données sont gérés. Vous n'avez pas le choix d'encodages Unicode comme le permettent certains autres RDBMS.

Vous pouvez insérer du code XML encodé en UTF-8 dans SQL Server, à condition de suivre ces trois règles :

  1. La chaîne entrante doit être de type de données VARCHAR , pas NVARCHAR (comme NVARCHAR est toujours UTF-16 Little Endian, d'où l'erreur de ne pas pouvoir changer d'encodage).
  2. Le XML a une déclaration XML qui indique explicitement que l'encodage du XML est bien UTF-8 :<?xml version="1.0" encoding="UTF-8" ?> .
  3. La séquence d'octets doit correspondre aux octets UTF-8 réels.

Par exemple, nous pouvons importer un document XML encodé en UTF-8 contenant l'emoji au visage hurlant (et nous pouvons obtenir la séquence d'octets UTF-8 pour ce caractère supplémentaire en suivant ce lien) :

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

Retourne (dans les onglets "Résultats" et "Messages") :

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

Vous avez mentionné dans un commentaire sur la réponse de @Shnugo :

Je n'ai rencontré aucun problème pour insérer des flux encodés en utf-8 avec un en-tête utf-8 dans la colonne SQL Server 2013 NVARCHAR. Y aurait-il un problème caché ?

Non, vous n'avez rien stocké en UTF-8 dans un NVARCHAR colonne (de plus, il n'y a pas de version 2013 de SQL Server, mais ce n'est probablement qu'une faute de frappe). NVARCHAR est toujours UTF-16 Little Endian. Très probablement, votre flux UTF-8 a été converti en UTF-16 LE par le pilote de base de données lors du transit vers SQL Server. Il s'agit du même encodage qu'une colonne XML utiliserait, mais la colonne XML aurait tenté de convertir le flux UTF-8 en UTF-16 mais aurait échoué car il s'agissait déjà d'UTF-16. Cela signifie également qu'à la sortie de SQL Server, le document XML stocké dans le NVARCHAR la colonne aurait toujours la déclaration XML indiquant que l'encodage est UTF-8, mais ce n'est certainement pas UTF-8.

Si vous avez absolument besoin que les données soient UTF-8 à la sortie parce que vous ne voulez pas convertir l'UTF-16 LE sortant de SQL Server XML ou NVARCHAR en UTF-8, alors vous n'avez pas d'autre choix que de stocker les données en tant que VARBINARY(MAX) .