2012-04-13 3 views
5

Я пытаюсь вставить некоторые двоичные данные в базу данных MySQL без использования подготовленных операторов. Причиной этого является то, что я объединяю тысячи операторов в одну вставку, которая запускается один раз. (Точно как MySQL дамп & импорт работ)Вставка двоичных данных в MySQL (без PreparedStatement)

Я попытался следующие утверждения, но все неудачу:

INSERT INTO my_table VALUES (1, 'г = F |} Х», 2);

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

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

INSERT INTO my_table ЗНАЧЕНИЯ (1, Бинарные 'г = F |} X', 2)

Ошибки я получаю:

усечение данных: com.mysql.jdbc.MysqlDataTruncation данных слишком долго для столбца «binary_data» в строке 1

код я использую, чтобы выполнить оператор просто:

conn.createStatement(). ExecuteUpdate (sql);

PreparedStatements работают отлично (но слишком медленно, в данном случае)

Фактическая строка I в базе данных показывает немного гладкошерстных:

г = ÷ ПОРАЖЕНИЯ | ¸} X £ ì [

Двоичный Вид: 67 3d 81 f7 19 f3 46 7c 7d b8 58 8с 10 а3 ес 5b

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

Это может быть связано с кодированием?

Любые намеки много apprecaited, Ro

+3

двоичные данные могут быть вставлены только через 'PreparedStatement' ИЛИ' CallableStatement' и не возможно, используя простой 'Statement'. –

+2

Вы знаете, что «оптимизация», которую вы сделали, вероятно, бесполезна? Точка подготовленных заявлений состоит в том, что они «предварительно скомпилированы» MySQL, и вы просто загружаете MySQL параметры. Если вы объединяете заявления или нет, вы все равно отправляете тысячи значений. И, естественно, это оказалось проблемой, поскольку вы не можете легко вставить двоичные данные. –

+0

Как вы генерируете заявления 'INSERT'? Кодирование, вероятно, имеет значение, но вам также нужно беспокоиться о правильном экранировании (например, если в двоичных данных есть '' '). Также вы проверяете свои JDBC [параметры подключения] (http://dev.mysql.com/doc/refman/5.5/en/connector-j-reference-configuration-properties.html), такие как 'useUnicode' и' characterEncoding '? –

ответ

11

Найдено решение .... Хотя это не то, что я видел, документированы где .... ,

Вы можете вставить двоичные данные непосредственно путем записи байтов преобразуются в HEX и предваряться 0x

Например:

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

Я не понимал, что mysql автоматически расшифровывает шестнадцатеричный код, спасибо за этот полезный пост. – fabspro

+1

Также обозначена нотация x'19c0300dc90e7cedf64703ed8ae8683b. Все это описано в разделе 9.1.4 Справочного руководства по MySQL. – olefevre

2

Готовое заявление, несомненно, самый быстрый подход. Причина, по которой вы находите ее слишком медленной, может быть связана с тем, что вы не используете ее внутри транзакции. Возможно, вы сможете сделать что-то милое с базой 64, но это будет очень медленно.

3

Вы пытались использовать PreparedStatement в пакетном режиме?

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

Для получения более подробной информации о том, как вы можете сделать Порции эффективным с JDBC и MySQL посмотрите здесь: MySQL and JDBC with rewriteBatchedStatements=true

+0

+1 для пакетного режима. –

+0

Yep - уже выдает 2000 выводов за один раз. Попытка написать что-то более быстрое, чем стандартный импорт mysql (с дополнительными настраиваемыми функциями) Текущая производительность на 40% медленнее, чем стандартный импорт, хотя я обрабатываю параллельно. PreparedStatements являются самыми медленными) –

+0

@Ro. Итак, PreparedStatement не медленнее, чем Stamement. Если это так, вы должны задать вопрос о том, почему это так, потому что этого не должно быть. –