¿Hay alguna manera de definir una columna/campo de SQL Server con codificación UTF-8?
No, la única codificación Unicode en SQL Server es UTF-16 Little Endian, que es como NCHAR
, NVARCHAR
, NTEXT
(en desuso a partir de SQL Server 2005, así que no lo use en un nuevo desarrollo; además, apesta en comparación con NVARCHAR(MAX)
de todos modos), y XML
Se manejan tipos de datos. No tiene la opción de codificaciones Unicode como lo permiten otros RDBMS.
Puede insertar XML codificado en UTF-8 en SQL Server, siempre que siga estas tres reglas:
- La cadena entrante debe ser del tipo de datos
VARCHAR
, noNVARCHAR
(comoNVARCHAR
siempre es UTF-16 Little Endian, de ahí el error de no poder cambiar la codificación). - El XML tiene una declaración XML que establece explícitamente que la codificación del XML es UTF-8:
<?xml version="1.0" encoding="UTF-8" ?>
. - La secuencia de bytes debe ser los bytes UTF-8 reales.
Por ejemplo, podemos importar un documento XML codificado en UTF-8 que contenga el emoji de la cara gritando (y podemos obtener la secuencia de bytes UTF-8 para ese carácter complementario siguiendo ese enlace):
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);
Devoluciones (en las pestañas "Resultados" y "Mensajes"):
<root><test>😱</test></root>
Mencionaste en un comentario sobre la respuesta de @Shnugo:
No he tenido problemas para insertar flujos codificados en utf-8 con encabezado utf-8 en la columna NVARCHAR de SQL Server 2013. ¿Habría algún problema oculto?
No, no almacenó nada codificado en UTF-8 en un NVARCHAR
columna (además, no hay una versión 2013 de SQL Server, pero probablemente sea solo un error tipográfico). NVARCHAR
es solo UTF-16 Little Endian. Lo más probable es que el controlador de la base de datos haya convertido su transmisión UTF-8 en UTF-16 LE durante el tránsito a SQL Server. Esta es la misma codificación que usaría una columna XML, pero la columna XML habría intentado convertir la transmisión de UTF-8 a UTF-16 pero falló debido a que ya era UTF-16. Esto también significa que al salir de SQL Server, el documento XML almacenado en el NVARCHAR
la columna aún tendría la declaración XML que indica que la codificación es UTF-8, pero definitivamente no es UTF-8.
Si necesita absolutamente que los datos sean UTF-8 al salir porque no quiere convertir el UTF-16 LE que sale de SQL Server XML
o NVARCHAR
en UTF-8, entonces no tiene más remedio que almacenar los datos como VARBINARY(MAX)
.