sql >> Database >  >> RDS >> Sqlserver

freebcp:Unicode-gegevens hebben een oneven bytegrootte voor kolom. Moet even byte zijn

Update:dit probleem is blijkbaar opgelost in FreeTDS v1.00.16, uitgebracht op 2016-11-04.

Ik kan uw probleem reproduceren met FreeTDS v1.00.15. Het lijkt zeker op een bug in freebcp waardoor het mislukt wanneer het laatste teken van een tekstveld een Unicode-codepunt heeft van de vorm U+20xx . (Met dank aan @srutzky voor het corrigeren van mijn conclusie over de oorzaak.) Zoals je hebt opgemerkt, werkt dit ...

291054  Ţawī Rifā

... en dit mislukt ...

291054  Ţawī Rifā‘

... maar ik ontdekte dat dit ook werkt:

291054  Ţawī Rifā‘x

Een lelijke oplossing zou dus zijn om een ​​script uit te voeren tegen uw invoerbestand dat een Unicode-teken van lage orde zonder spatie aan elk tekstveld zou toevoegen (bijv. x dat is U+0078 , zoals in het laatste voorbeeld hierboven), gebruik freebcp om de gegevens te uploaden en voer vervolgens een UPDATE uit statement tegen de geïmporteerde rijen om het extra teken te verwijderen.

Persoonlijk zou ik geneigd zijn om over te stappen van FreeTDS naar Microsoft's SQL Server ODBC Driver voor Linux, inclusief de bcp en sqlcmd hulpprogramma's indien geïnstalleerd met behulp van de hier beschreven instructies:

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

Ik heb het net getest onder Xubuntu 16.04, en hoewel ik de procedure een beetje moest aanpassen om libssl.so.1.0.0 te gebruiken in plaats van libssl.so.0.9.8 (en hetzelfde voor libcrypto ), toen ik het eenmaal had geïnstalleerd, de bcp hulpprogramma van Microsoft is geslaagd waar freebcp mislukt.

Als het SQL Server ODBC-stuurprogramma voor Linux niet werkt op een Mac, is een ander alternatief het gebruik van het Microsoft JDBC-stuurprogramma 6.0 voor SQL Server en een klein beetje Java-code, zoals deze:

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


  1. Hoe zorg ik ervoor dat SQL Server een login vindt die overeenkomt met de opgegeven naam?

  2. MYSQL Dump alleen bepaalde rijen

  3. Retourneer het aantal rijen dat wordt beïnvloed door de SQL UPDATE-instructie in Java

  4. SYSDATETIME() Voorbeelden in SQL Server (T-SQL)