2012-04-13 18 views
5

Próbuję wstawić niektóre dane binarne do bazy danych MySQL bez użycia gotowych instrukcji. Powodem tego jest to, że łączę tysiące instrukcji w jeden insert i raz. (Dokładnie w jaki sposób MySQL zrzucić & prace importu)Wstawianie danych binarnych do MySQL (bez PreparedStatement)

Próbowałem następujące oświadczenia, ale są wszystkie braku:

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

INSERT TO my_table VALUES (1, CAST ('g = F | } X ' AS BINARY), 2);

INSERT TO my_table VALUES (1, CONVERT ("g = F | } X ", BINARY), 2);

INSERT INTO my_table wartości (1, binarny 'g = F |} X', 2)

Błąd pojawia się:

obcięcie danych:: com.mysql.jdbc.MysqlDataTruncation dane zbyt długo na kolumnie „binary_data” w wierszu 1

Kod używam do wykonania instrukcji jest po prostu:

conn.createStatement(). ExecuteUpdate (sql);

PreparedStatements działać dobrze (ale są zbyt powolne w tym przypadku)

Rzeczywista String I w bazie wyświetla trochę differet:

g = ÷ od | ¸} X £ ì [

binarne Widok: 67 3d 81 F7 19 F3 46 B8 7c 7d 58 8c 10 A3 we 5b

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

Czy może to mieć coś wspólnego z kodowaniem?

Wszelkie wskazówki znacznie apprecaited, Ro

+3

dane binarne można włożyć tylko przez 'PreparedStatement' lub' CallableStatement' i nie możliwe za pomocą prostego "Statement". –

+2

Czy wiesz, że "optymalizacja", którą zrobiłeś, jest prawdopodobnie bezwartościowa? Punktem przygotowanych wypowiedzi jest to, że są one "prekompilowane" przez MySQL i po prostu przekazujesz MySQL parametry. Niezależnie od tego, czy łączysz oświadczenia, czy nie, i tak przesyłasz tysiące wartości. I oczywiście okazało się to problemem, ponieważ nie można łatwo wstawić danych binarnych. –

+0

W jaki sposób generujesz swoje instrukcje 'INSERT'? Kodowanie prawdopodobnie ma znaczenie, ale musisz także martwić się o prawidłowe usuwanie (np. Jeśli dane binarne mają w sobie '' '). Sprawdzasz także JDBC [parametry połączenia] (http://dev.mysql.com/doc/refman/5.5/en/connector-j-reference-configuration-properties.html), takie jak 'useUnicode' i' characterEncoding '? –

Odpowiedz

11

Znaleziono rozwiązanie .... chociaż nie coś widziałem nigdzie udokumentowane .... .

Można wstawić dane binarne bezpośrednio pisząc bajty zamienione na HEX i poprzedzone 0x

Na przykład:

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

Nie wiedziałem, że mysql automatycznie dekoduje hex, dzięki za pomocny wpis. – fabspro

+1

Notacja x'19c0300dc90e7cedf64703ed8ae8683b 'działa również. Wszystko to jest udokumentowane w § 9.1.4 Podręcznika referencyjnego MySQL. – olefevre

2

przygotowane oświadczenie jest niewątpliwie najszybszy podejście. Powodem, dla którego uważasz, że jest zbyt wolny, może być fakt, że nie używasz go w ramach transakcji. Możesz zrobić coś słodkiego z base 64, ale będzie to bardzo powolne.

3

Czy próbowałeś użyć PreparedStatement w trybie wsadowym?

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

celu uzyskania bardziej szczegółowych informacji o tym, jak można zrobić Partie wydajny z JDBC i MySQL zajrzyj tutaj: MySQL and JDBC with rewriteBatchedStatements=true

+0

+1 dla trybu wsadowego. –

+0

Yep - już wsadowy 2000 oświadczeń na raz. Próbuję napisać coś szybciej niż standardowe importowanie MySQL (z dodatkowymi niestandardowymi funkcjami) PreparedStatements są najwolniejsze) –

+0

@Ro. Więc, PreparedStatement nie jest wolniejszy niż Stamement. Jeśli tak, powinieneś zadać pytanie, dlaczego tak jest, ponieważ tak nie powinno być. –

Powiązane problemy