sql >> Base de Datos >  >> RDS >> Sqlserver

freebcp:los datos Unicode tienen un tamaño de bytes impar para la columna. Debe tener un tamaño de byte uniforme

Actualización:este problema aparentemente se solucionó en FreeTDS v1.00.16, lanzado el 2016-11-04.

Puedo reproducir su problema usando FreeTDS v1.00.15. Definitivamente parece un error en freebcp eso hace que falle cuando el último carácter de un campo de texto tiene un punto de código Unicode de la forma U+20xx . (Gracias a @srutzky por corregir mi conclusión sobre la causa). Como notó, esto funciona...

291054  Ţawī Rifā

... y esto falla...

291054  Ţawī Rifā‘

... pero descubrí que esto también funciona:

291054  Ţawī Rifā‘x

Por lo tanto, una solución fea sería ejecutar un script en su archivo de entrada que agregaría un carácter Unicode sin espacio de orden bajo a cada campo de texto (por ejemplo, x que es U+0078 , como en el último ejemplo anterior), use freebcp para cargar los datos y luego ejecutar UPDATE contra las filas importadas para eliminar el carácter extra.

Personalmente, me inclinaría por cambiar de FreeTDS al controlador ODBC de SQL Server de Microsoft para Linux, que incluye el bcp y sqlcmd utilidades cuando se instala siguiendo las instrucciones descritas aquí:

https://gallery.technet.microsoft.com /scriptcenter/SQLCMD-and-BCP-for-Ubuntu-c88a28cc

Acabo de probarlo en Xubuntu 16.04, y aunque tuve que modificar un poco el procedimiento para usar libssl.so.1.0.0 en lugar de libssl.so.0.9.8 (y lo mismo para libcrypto ), una vez que lo instalé bcp La utilidad de Microsoft tuvo éxito donde freebcp fallado.

Si el controlador ODBC de SQL Server para Linux no funciona en una Mac, otra alternativa sería usar el controlador JDBC de Microsoft 6.0 para SQL Server y un poco de código Java, como este:

connectionUrl = "jdbc:sqlserver://servername:49242"
        + ";databaseName=myDb"
        + ";integratedSecurity=false";
String myUserid = "sa", myPassword = "whatever";

String dataFileSpec = "C:/Users/Gord/Desktop/bad.txt";
try (
        Connection conn = DriverManager.getConnection(connectionUrl, myUserid, myPassword);
        SQLServerBulkCSVFileRecord fileRecord = new SQLServerBulkCSVFileRecord(dataFileSpec, "UTF-8", "\t", false);
        SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(conn)) {
    fileRecord.addColumnMetadata(1, "col1", java.sql.Types.NVARCHAR, 50, 0);
    fileRecord.addColumnMetadata(2, "col2", java.sql.Types.NVARCHAR, 50, 0);
    bulkCopy.setDestinationTableName("dbo.freebcptest");
    bulkCopy.writeToServer(fileRecord);
} catch (Exception e) {
    e.printStackTrace(System.err);
}