convert - ¿Cómo escribir caracteres UTF-8 utilizando inserciones masivas en SQL Server?
sql server utf-8 convert (12)
Estoy haciendo un INSERTO A GRANEL en sqlserver y no está insertando correctamente los caracteres UTF-8 en la base de datos. El archivo de datos contiene estos caracteres, pero las filas de la base de datos contienen caracteres de basura después de la ejecución de la inserción masiva.
Mi primer sospechoso fue la última línea del archivo de formato:
10.0
3
1 SQLCHAR 0 0 "{|}" 1 INSTANCEID ""
2 SQLCHAR 0 0 "{|}" 2 PROPERTYID ""
3 SQLCHAR 0 0 "[|]" 3 CONTENTTEXT "SQL_Latin1_General_CP1_CI_AS"
Pero, después de leer esta página oficial, me parece que esto es realmente un error al leer el archivo de datos por la operación de inserción en SQL Server versión 2008. Estamos utilizando la versión 2008 R2.
¿Cuál es la solución a este problema o al menos una solución?
- En Excel guardar archivo como CSV (delimitado por comas)
- Abrir archivo CSV guardado en notepad ++
- Codificación -> Convertir tO UCS-2 Big Endian
- Salvar
GRAN INSERTAR #tmpData
FROM ''C:/Book2.csv'' WITH ( FIRSTROW = 2, FIELDTERMINATOR = '';'', --CSV field delimiter ROWTERMINATOR = ''/n'', --Use to shift the control to next row TABLOCK )
Hecho.
¿No debería utilizar SQLNCHAR
lugar de SQLCHAR
para los datos de Unicode?
He probado la inserción masiva con el formato UTF -8
. Funciona bien en Sql Server 2012.
string bulkInsertQuery = @"DECLARE @BulkInsertQuery NVARCHAR(max) = ''bulk insert [dbo].[temp_Lz_Post_Obj_Lvl_0]
FROM ''''C://Users//suryan//Desktop//SIFT JOB//New folder//POSTdata_OBJ5.dat''''
WITH ( FIELDTERMINATOR = ''''''+ CHAR(28) + '''''', ROWTERMINATOR = '''''' +CHAR(10) + '''''')''
EXEC SP_EXECUTESQL @BulkInsertQuery";
Estaba usando el archivo *.DAT
con FS como separador de columna.
Logré hacer esto usando SSIS y un destino ADO NET en lugar de OLEDB.
Microsoft acaba de agregar soporte para UTF-8 a SQL Server 2014 SP2:
Mis datos exportados están en formato TSV desde DB que tiene codificación Latin-1.
Esto es fácil de verificar: SELECT DATABASEPROPERTYEX(''DB'', ''Collation'') SQLCollation;
El archivo de extracción está en formato UTF-8.
BULK INSERT no funciona con UTF-8, así que convierto UTF-8 a ISO-8859-1 (también conocido como Latin-1) con un sencillo script de Clojure:
(spit ".//dump//file1.txt" (slurp ".//dump//file1_utf8.txt" :encoding "UTF-8") :encoding "ISO-8859-1")
Para ejecutar: corregir las rutas y java.exe -cp clojure-1.6.0.jar clojure.main utf8_to_Latin1.clj
Pensé que añadiría mis pensamientos a esto. Estábamos tratando de cargar datos en SqlServer usando bcp y tuvimos muchos problemas.
bcp no admite, en la mayoría de las versiones, ningún tipo de archivos UTF-8. Descubrimos que UTF-16 funcionaría, pero es más complejo de lo que se muestra en estas publicaciones.
Usando Java escribimos el archivo usando este código:
PrintStream fileStream = new PrintStream(NEW_TABLE_DATA_FOLDER + fileName, "x-UTF-16LE-BOM");
Esto nos dio los datos correctos para insertar.
Intentamos usar solo UTF16 y seguimos obteniendo errores EOF. Esto es porque nos faltaba la parte de la lista de materiales del archivo. De Wikipedia:
UTF-16, una lista de materiales (U + FEFF) se puede colocar como el primer carácter de un archivo o flujo de caracteres para indicar la endianidad (orden de bytes) de todas las unidades de código de 16 bits del archivo o flujo.
Si estos bytes no están presentes, el archivo no funcionará. Así que tenemos el archivo, pero hay un secreto más que debe abordarse. Al construir su línea de comando, debe incluir -w para decirle a bcp qué tipo de datos es. Cuando solo usas datos en inglés, puedes usar -c (carácter). Así que se verá algo como esto:
bcp dbo.blah en C: / Users / blah / Desktop / events / blah.txt -S tcp: databaseurl, someport -d thedatabase -U nombre de usuario -P contraseña -w
Cuando todo esto esté hecho, obtendrás algunos datos de aspecto dulce.
Puede volver a codificar el archivo de datos con UTF-16. Eso es lo que hice de todos modos.
Tenga en cuenta que a partir de Microsoft SQL Server 2016, UTF-8 es compatible con bcp
, BULK_INSERT
(como parte de la pregunta original) y OPENROWSET
.
Usted no puede Primero debe usar un campo de datos de tipo N, convertir su archivo a UTF-16 y luego importarlo. La base de datos no es compatible con UTF-8.
Utilice estas opciones: DATAFILETYPE=''char''
y CODEPAGE = ''1252''
Vine aquí antes de buscar una solución para la inserción masiva de caracteres especiales. No me gustó la solución con UTF-16 (que duplicaría el tamaño del archivo csv). Descubrí que definitivamente PUEDES y es muy fácil, no necesitas un archivo de formato. Así que estoy agregando este comentario para otras personas que están buscando lo mismo, ya que no parece estar bien documentado en ninguna parte, y creo que este es un problema muy común para las personas que no hablan inglés. La solución es: simplemente agregue CODEPAGE = ''65001'' dentro de la declaración with del inserto masivo. (65001 = número de página de código para UTF-8). Puede que no funcione para todos los caracteres Unicode como lo sugiere Michael O, pero al menos funciona perfecto para latinos, griegos y cirílicos, probablemente muchos otros también.
Nota: la documentación de MSDN dice que utf-8 no es compatible, no lo crea, para mí esto funciona perfectamente en el servidor SQL 2008, sin embargo, no probé otras versiones.
p.ej:
BULK INSERT #myTempTable
FROM ''D:/somefolder/myCSV.txt''+
WITH
(
CODEPAGE = ''65001'',
FIELDTERMINATOR = ''|'',
ROWTERMINATOR =''/n''
);
Si todos sus caracteres especiales están en 160-255 (iso-8859-1 o windows-1252), también podría usar:
BULK INSERT #myTempTable
FROM ''D:/somefolder/myCSV.txt''+
WITH
(
CODEPAGE = ''ACP'',
FIELDTERMINATOR = ''|'',
ROWTERMINATOR =''/n''
);