2012-04-13 56 views
5

Tôi đang cố gắng chèn một số dữ liệu nhị phân vào cơ sở dữ liệu MySQL mà không sử dụng câu lệnh đã chuẩn bị. Lý do cho điều này là tôi nối vào hàng nghìn câu lệnh thành một lần chèn một lần chạy một lần. (Chính xác như thế nào MySQL đổ & công trình nhập khẩu)Chèn dữ liệu nhị phân vào MySQL (không có PreparedStatement)

Tôi đã thử những điều khoản sau đây, nhưng tất cả các thất bại:

INSERT INTO GIÁ TRỊ my_table (1, 'g = F |} X ', 2);

INSERT INTO giá trị my_table (1, CAST ('g = F | } X ' NHƯ NGÂN HÀNG), 2);

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

INSERT INTO GIÁ TRỊ my_table (1, Binary 'g = F |} X', 2)

Các lỗi tôi nhận được là:

com.mysql.jdbc.MysqlDataTruncation: Cắt dữ liệu: Dữ liệu quá dài cho cột 'binary_data' ở hàng 1

Mã tôi sử dụng để thực hiện câu lệnh đơn giản là:

conn.createStatement(). ExecuteUpdate (sql);

PreparedStatements làm việc tốt (nhưng là quá chậm trong trường hợp này)

Các chuỗi thực tế I trong cơ sở dữ liệu sẽ hiển thị một chút differet:

g = ÷ của | ¸} ì X £ [

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

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

Điều này có liên quan gì đến Mã hóa không?

Bất kỳ gợi ý nhiều apprecaited, Ro

+3

Dữ liệu nhị phân có thể được chèn chỉ qua 'PreparedStatement' hoặc' CallableStatement' và không có thể sử dụng 'Statement' đơn giản. –

+2

Bạn biết rằng "tối ưu hóa" bạn đã làm có lẽ vô giá trị? Điểm của các câu lệnh chuẩn bị là chúng được "biên dịch trước" bởi MySQL và bạn chỉ cần cung cấp các tham số cho MySQL. Cho dù bạn có ghép nối hay không, bạn vẫn gửi hàng nghìn giá trị. Và tự nhiên, điều này hóa ra là một vấn đề vì bạn không thể dễ dàng chèn dữ liệu nhị phân. –

+0

Bạn tạo các câu lệnh 'INSERT' như thế nào? Mã hóa các vấn đề có thể xảy ra, nhưng bạn cũng phải lo lắng về việc thoát đúng (ví dụ: nếu dữ liệu nhị phân có ''' trong đó). Bạn cũng kiểm tra JDBC [tham số kết nối] (http://dev.mysql.com/doc/refman/5.5/en/connector-j-reference-configuration-properties.html), chẳng hạn như 'useUnicode' và' characterEncoding '? –

Trả lời

11

Tìm thấy giải pháp .... Mặc dù không phải cái gì tôi thấy tài liệu bất cứ nơi nào .... .

Bạn có thể chèn dữ liệu nhị phân trực tiếp bằng cách viết các byte chuyển đổi sang HEX và preceeded bởi 0x

Ví dụ:

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

Tôi đã không nhận ra mysql tự động giải mã hex như vậy, nhờ bài viết hữu ích này. – fabspro

+1

Ký hiệu x'19c0300dc90e7cedf64703ed8ae8683b 'cũng hoạt động. Đây là tất cả các tài liệu trong §9.1.4 của Hướng dẫn tham khảo MySQL. – olefevre

2

Một tuyên bố chuẩn bị chắc chắn là cách tiếp cận nhanh nhất. Lý do bạn thấy nó quá chậm có thể là do bạn không sử dụng nó bên trong một giao dịch. Bạn có thể làm điều gì đó dễ thương với base 64, nhưng nó sẽ rất chậm.

3

Bạn đã cố gắng sử dụng PreparedStatement ở chế độ Hàng loạt chưa?

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

Để biết thông tin chi tiết hơn về cách bạn có thể thực hiện một loạt hiệu quả với JDBC và MySQL có một cái nhìn ở đây: MySQL and JDBC with rewriteBatchedStatements=true

+0

+1 cho chế độ hàng loạt. –

+0

Đúng - Đã Batching 2000 Các câu lệnh tại một thời điểm. Cố gắng viết nhanh hơn nhập chuẩn mysql (với các tính năng tùy chỉnh bổ sung) Hiệu suất hiện tại chậm hơn 40% so với nhập chuẩn, mặc dù tôi đang xử lý song song - Bảng có cột nhị phân (mà tôi đang xử lý bằng Bản tuyên bố đã chuẩn bị là chậm nhất) –

+0

@Ro. Vì vậy, sau đó PreparedStatement không chậm hơn so với Stamement. Nếu có, bạn nên đặt câu hỏi về lý do tại sao, bởi vì nó không nên. –

Các vấn đề liên quan