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

freebcp:os dados Unicode têm um tamanho de byte ímpar para a coluna. Deve ter um tamanho de byte uniforme


Atualização:Este problema aparentemente foi corrigido no FreeTDS v1.00.16, lançado em 2016-11-04.

Posso reproduzir seu problema usando o FreeTDS v1.00.15. Definitivamente, parece um bug no freebcp que faz com que ele falhe quando o último caractere de um campo de texto tem um ponto de código Unicode no formato U+20xx . (Obrigado a @srutzky por corrigir minha conclusão quanto à causa.) Como você observou, isso funciona ...
291054  Ţawī Rifā

... e isso falha ...
291054  Ţawī Rifā‘

... mas descobri que isso também funciona:
291054  Ţawī Rifā‘x

Portanto, uma solução feia seria executar um script em seu arquivo de entrada que anexaria um caractere Unicode sem espaço de ordem inferior a cada campo de texto (por exemplo, x que é U+0078 , como no último exemplo acima), use freebcp para carregar os dados e, em seguida, execute um UPDATE instrução contra as linhas importadas para remover o caractere extra.

Pessoalmente, eu estaria inclinado a mudar do FreeTDS para o SQL Server ODBC Driver for Linux da Microsoft, que inclui o bcp e sqlcmd utilitários quando instalados usando as instruções descritas aqui:

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

Acabei de testar no Xubuntu 16.04 e, embora tenha que ajustar um pouco o procedimento para usar libssl.so.1.0.0 em vez de libssl.so.0.9.8 (e o mesmo para libcrypto ), uma vez que eu instalei o bcp utilitário da Microsoft teve sucesso onde freebcp fracassado.

Se o driver ODBC do SQL Server para Linux não funcionar em um Mac, outra alternativa seria usar o Microsoft JDBC Driver 6.0 para SQL Server e um pouco 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);
}