Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

freebcp:i dati Unicode sono di dimensioni dispari in byte per la colonna. Dovrebbe essere pari alla dimensione del byte

Aggiornamento:questo problema è stato apparentemente risolto in FreeTDS v1.00.16, rilasciato il 04-11-2016.

Posso riprodurre il tuo problema usando FreeTDS v1.00.15. Sembra decisamente un bug in freebcp che fa fallire quando l'ultimo carattere di un campo di testo ha un punto di codice Unicode del formato U+20xx . (Grazie a @srutzky per aver corretto la mia conclusione sulla causa.) Come hai notato, funziona ...

291054  Ţawī Rifā

... e questo non riesce ...

291054  Ţawī Rifā‘

... ma ho scoperto che funziona anche questo:

291054  Ţawī Rifā‘x

Quindi, una brutta soluzione sarebbe eseguire uno script sul tuo file di input che aggiungerebbe un carattere Unicode di ordine inferiore non spazio a ciascun campo di testo (ad esempio, x che è U+0078 , come nell'ultimo esempio sopra), usa freebcp per caricare i dati, quindi eseguire un UPDATE istruzione contro le righe importate per rimuovere il carattere extra.

Personalmente, sarei propenso a passare da FreeTDS a SQL Server ODBC Driver per Linux di Microsoft, che include il bcp e sqlcmd utility una volta installato utilizzando le istruzioni descritte qui:

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

L'ho appena testato con Xubuntu 16.04, e anche se ho dovuto modificare un po' la procedura per usare libssl.so.1.0.0 invece di libssl.so.0.9.8 (e lo stesso per libcrypto ), una volta installato il bcp l'utilità di Microsoft è riuscita dove freebcp fallito.

Se il driver ODBC di SQL Server per Linux non funziona su un Mac, un'altra alternativa sarebbe utilizzare il driver Microsoft JDBC 6.0 per SQL Server e un po' di codice Java, come questo:

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