Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

freebcp:Unicode-Daten haben eine ungerade Bytegröße für die Spalte. Sollte eine gerade Bytegröße haben

Update:Dieses Problem wurde offenbar in FreeTDS v1.00.16, veröffentlicht am 04.11.2016, behoben.

Ich kann Ihr Problem mit FreeTDS v1.00.15 reproduzieren. Es sieht definitiv nach einem Fehler in freebcp aus Dies führt dazu, dass es fehlschlägt, wenn das letzte Zeichen eines Textfelds einen Unicode-Codepunkt der Form U+20xx hat . (Danke an @srutzky für die Korrektur meiner Schlussfolgerung zur Ursache.) Wie Sie bemerkt haben, funktioniert dies ...

291054  Ţawī Rifā

... und das schlägt fehl ...

291054  Ţawī Rifā‘

... aber ich habe festgestellt, dass dies auch funktioniert:

291054  Ţawī Rifā‘x

Eine hässliche Problemumgehung wäre also, ein Skript für Ihre Eingabedatei auszuführen, das ein Unicode-Zeichen niedriger Ordnung ohne Leerzeichen an jedes Textfeld anhängt (z. B. x das ist U+0078 , wie im letzten Beispiel oben), verwenden Sie freebcp um die Daten hochzuladen, und führen Sie dann ein UPDATE aus -Anweisung gegen die importierten Zeilen, um das zusätzliche Zeichen zu entfernen.

Ich persönlich würde eher von FreeTDS zu Microsofts SQL Server ODBC-Treiber für Linux wechseln, der den bcp enthält und sqlcmd Dienstprogramme, wenn sie mit den hier beschriebenen Anweisungen installiert werden:

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

Ich habe es gerade unter Xubuntu 16.04 getestet, und obwohl ich das Verfahren ein wenig anpassen musste, um libssl.so.1.0.0 zu verwenden statt libssl.so.0.9.8 (und dasselbe für libcrypto ), nachdem ich es installiert hatte, installierte ich den bcp Dienstprogramm von Microsoft erfolgreich, wo freebcp fehlgeschlagen.

Wenn der SQL Server ODBC-Treiber für Linux auf einem Mac nicht funktioniert, wäre eine andere Alternative die Verwendung des Microsoft JDBC-Treibers 6.0 für SQL Server und ein bisschen Java-Code, wie hier:

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