Crea un file in Java per il caricamento in un campo nvarchar in SQLServer 2005 utilizzando BCP e UTF-16

StackOverflow https://stackoverflow.com/questions/2246355

Domanda

Desidero utilizzare BCP per caricare in una tabella SQL Server 2005 con un campo nvarchar utilizzando un file di controllo del caricatore.A quanto ho capito, SQL Server 2005 supporta solo UTF-16 (e credo che sia UTF-16 LE).Il file viene generato da un programma Java.Il modo in cui l'ho attualmente impostato è il seguente:

  1. Un file di caricamento BCP in formato XML (creato utilizzando il seguente comando:bcp test_table format nul -c -x -T -f test_table.xml -S server)

  2. Un programma Java che utilizza il seguente codice per scrivere l'output:

    File f = new File("from_java.txt");
    String encoding = "x-UTF-16LE-BOM";
    OutputStream os = new FileOutputStream(f);
    OutputStreamWriter outputStreamWriter = new OutputStreamWriter(os, encoding);
    String theString = "áááááLittle Endian, BOM\r\n";
    outputStreamWriter.append(theString);
    outputStreamWriter.flush();
    outputStreamWriter.close();
    
  3. Quindi utilizzando il seguente comando bcp:
    bcp test_table in from_java.txt -T -f test_table.xml -S server -error error.txt

Quello che ottengo nella tabella è ÿþá.e non áááááLittle Endian, BOM

Ho provato alcune diverse permutazioni di modifica dei parametri:

  • cambiando il modo in cui genero il file di controllo del caricatore (usando -n per i dati nativi invece di -c per i dati dei caratteri... penso che questo possa avere qualcosa a che fare con questo, ma non ho visto alcun miglioramento nei dati inseriti)
  • ho provato diverse forme di codifica UTF-16, inclusi big endian e little endian senza BOM, senza alcun risultato
  • ho provato a generare manualmente la distinta base nel file poiché ho letto da qualche parte che a Microsoft piace molto utilizzare le informazioni sulla distinta base
  • ho provato a provare a generare il file come UCS-2 (invece di UTF-16) poiché questo è (apparentemente) ciò in cui BCP sta effettivamente leggendo il file come
  • provato -w sull'importazione bcp, funziona, ma non insieme a un file di formato del caricatore (esiste un modo per incorporare qualunque magia dica a BCP che il file è codificato in UTF-16 nel file di formato?)
  • Posso farlo funzionare se eseguo il file in Windows-1252 e specifico quella codepage come a -c 1252 opzione per bcp quando carico il file (ma non voglio farlo perché perderò informazioni poiché UTF-16 è un superset di ciò che può essere rappresentato rispetto a 1252)

Qualcuno è riuscito a caricare bcp in un campo nvarchar utilizzando i dati UTF-16 insieme a un file di configurazione del formato del caricatore?

Grazie in anticipo,

-Giacomo

È stato utile?

Soluzione

Sono stato letteralmente deluso dalle risposte, ma ce l'ho fatta.

Il file del caricatore deve essere generato con a -w flag, quindi il comando per generare il file è:

bcp <table> format nul -w -x T -f loader-control-w-format.xml -S <server> -t "||"

Ciò porta a un file di controllo del caricatore che appare leggermente diverso, ottieni voci come:

<FIELD ID="1" xsi:type="NCharTerm" TERMINATOR="|\0|\0" MAX_LENGTH="1000" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>

Tieni presente che il delimitatore è elencato come |\0|\0, gli zeri corrispondono al byte aggiuntivo nel file poiché UTF-16 (o semplicemente "unicode" come lo chiama (erroneamente) Microsoft) è una codifica di caratteri a doppio byte.

Alcune note per la sanità mentale di chiunque altro abbia a che fare con BCP in questo modo:

  • Quando SQLServer parla di "nativo" intende caratteri nativi, ad es.caratteri accentati
  • Quando SQLServer parla di Unicode, ciò che in realtà intende è il modo UTF16 (Little Endian) di codificare il Set di caratteri Unicode.Questo è ciò a cui si riferisce -w
  • Quando si scrive un file da caricare in BCP utilizzando UTF-16, il file deve essere in formato Little Endian UTF-16 e non può contenere una BOM UTF (poiché BCP lo interpreterà come un byte che dovrebbe essere caricato e il primo record conterrà la distinta base, urgh!)

Il codice Java per scrivere un file in UTF-16 che può essere caricato in questo modo è il seguente:

    final File f = new File("C:\\temp\\bcp_prob\\from_java-UTF-16.txt");
    //LE with no BOM is important here:
    final String encoding = "UTF-16LE";
    final OutputStream os = new FileOutputStream(f);
    final OutputStreamWriter outputStreamWriter = new OutputStreamWriter(os, encoding);
    final String theString = "UTF-16-LE, intermetálico básicos intermetálico película magnética dinámicos||another_col\r\n";        
    outputStreamWriter.append(theString);
    outputStreamWriter.flush();
    outputStreamWriter.close();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top