2012-04-13 13 views
5

Sto cercando di inserire alcuni dati binari in un database MySQL senza utilizzare istruzioni preparate. La ragione di ciò è che concatenare migliaia di istruzioni in un singolo inserto e una sola esecuzione. (Esattamente come il MySQL discarica & opere di importazione)Inserimento di dati binari in MySQL (senza PreparedStatement's)

Ho provato le seguenti dichiarazioni, ma la sono tutti fallendo:

INSERT INTO VALORI my_table (1, 'g = F |} X', 2);

INSERIRE IN my_table VALORI (1, CAST ('g = F | } X ' COME BINARIO), 2);

INSERIRE IN my_table VALORI (1, CONVERT ('g = F | } X ', BINARY), 2);

INSERT INTO VALORI my_table (1, BINARIO 'g = F |} X', 2)

L'errore che ottengo è:

troncamento dei dati:: com.mysql.jdbc.MysqlDataTruncation dati troppo lungo per la colonna 'binary_data' alla riga 1

il codice che uso per eseguire l'istruzione è semplicemente:

conn.createStatement(). ExecuteUpdate (sql);

PreparedStatements funzionano bene (ma sono troppo lenti in questo caso)

la stringa effettiva che nel database viene visualizzato un po differet:

g = ÷ di | ¸} X £ ì [

Binary Vista: 67 3d 81 f7 f3 19 46 7c 7d b8 58 8c 10 a3 ec 5b

Java Byte: 103, 61, -127, -9, 25, -13, 70, 124, -72, 125, 88, -116, 16, -93, -20, 91

Potrebbe essere qualcosa a che fare con la codifica?

Eventuali suggerimenti molto apprecaited, Ro

+3

dati binari possono essere inseriti soltanto attraverso '' PreparedStatement' OR CallableStatement' e non possibile usando semplice 'Statement'. –

+2

Sai che l'ottimizzazione che hai fatto è probabilmente senza valore? Il punto delle affermazioni preparate è che sono "precompilate" da MySQL e si limitano a fornire a MySQL i parametri. Sia che si concatenano dichiarazioni o no, si inviano comunque migliaia di valori. E naturalmente, questo si è rivelato un problema poiché non è possibile inserire facilmente dati binari. –

+0

Come stai generando le tue istruzioni 'INSERT'? La codifica probabilmente conta, ma devi anche preoccuparti di eseguire correttamente l'escape (ad esempio se i dati binari hanno un '' 'in esso). Controlla anche il tuo JDBC [parametri di connessione] (http://dev.mysql.com/doc/refman/5.5/en/connector-j-reference-configuration-properties.html), come 'useUnicode' e' characterEncoding '? –

risposta

11

trovato la soluzione .... Anche se non è qualcosa che ho visto documentato da nessuna parte .... .

È possibile inserire dati binari direttamente scrivendo i byte convertiti in HEX e precedute da 0x

Ad esempio:

INSERT INTO my_table VALUES (1,0x19c0300dc90e7cedf64703ed8ae8683b,2); 
+1

Non sapevo che mysql decodifica automaticamente hex come quello, grazie per questo utile post. – fabspro

+1

Anche la notazione x'19c0300dc90e7cedf64703ed8ae8683b 'funziona. Tutto ciò è documentato in §9.1.4 del Manuale di riferimento MySQL. – olefevre

2

Una dichiarazione preparata è senza dubbio il metodo più veloce. Il motivo per cui lo trovi troppo lento potrebbe essere perché non lo stai utilizzando all'interno di una transazione. Potresti riuscire a fare qualcosa di carino con la base 64, ma sarebbe molto lento.

3

Hai provato a utilizzare PreparedStatement in modalità Batch?

PreparedStatement pStmt = ...; 
    while(...) { // use for or whatever loop 
     pStmt.clearParameters(); 
     pStmt.setBinaryStream(2, ...); 
     pStmt.addBatch(); 
    } 
    pStmt.executeBatch(); 

Per informazioni più dettagliate su come si può fare batch efficiente con JDBC e MySQL dare un'occhiata qui: MySQL and JDBC with rewriteBatchedStatements=true

+0

+1 per la modalità batch. –

+0

Sì, già batch di istruzioni 2000 alla volta. cercando di scrivere qualcosa di più veloce rispetto a MySQL standard di importazione (con funzioni personalizzate aggiuntive) prestazioni attuale è del 40% più lento di importazione di serie, anche se sono di elaborazione in parallelo - Le tabelle con le colonne binarie (che sto usando elaborazione Le Stats preparate sono le più lente) –

+0

@Ro. Quindi, PreparedStatement non è più lento di Stamement. Se lo è, dovresti fare una domanda sul perché lo è, perché non dovrebbe esserlo. –