c++ - MySql Connector 准备语句只传输 64 字节

标签 c++ mysql prepared-statement mysql-connector

我正在使用 MySql Connector C++ 将文件中的 JPEG 图像存储到数据库中。我正在使用准备好的声明。准备好的语句执行后,只有文件的前 64 个字节被复制到数据库中。

我对示例的研究表明不需要迭代,并且示例假定准备好的语句加载整个文件。这是我的代码:

std::string         statement_text("INSERT INTO ");
statement_text += "picture_image_data";
statement_text += " (";
statement_text += "ID_Picture";
statement_text += ", ";
statement_text += "Image_Data";
statement_text += ") VALUES (?, ?)";    
wxLogDebug("Creating prepared statement using:\n%s\n", statement_text.c_str());
std::string filename("my_image.jpg");
Ptr_Db_Connection                           db_conn(db_mgr.get_db_connection());
boost::shared_ptr<sql::PreparedStatement>   prepared_statement(db_conn->prepareStatement(statement_text));
prepared_statement->setInt(1, picture_id);
std::ifstream   blob_file(filename.c_str());
prepared_statement->setBlob(2, &blob_file);
prepared_statement->execute();
blob_file.close();

这是表的架构:

mysql> describe picture_image_data;
+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| ID_Picture | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| Image_Data | mediumblob       | YES  |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

从 MySql 控制台:

mysql> select ID_Picture, LENGTH(image_data)
    -> FROM picture_image_data
    -> where ID_Picture = 1;
+------------+--------------------+
| ID_Picture | LENGTH(image_data) |
+------------+--------------------+
|          1 |                 65 |
+------------+--------------------+
1 row in set (0.02 sec)

如何让预处理语句读取整个文件?
我是否需要在 MySql Connector C++ 中初始化任何内容以使其读取超过 64 个字节?

注意:我在 Windows XP 和 Vista 上使用 MySql Connector C++ 1.0.5、Visual Studio 2008 和 wxWidgets。

建表语句:

CREATE TABLE Picture_Image_Data
(
    ID_Picture INTEGER UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
    Image_Data MEDIUMBLOB
);

图像文件的十六进制转储(通过 Cygwin):

0000000 d8ff e0ff 1000 464a 4649 0100 0101 1c00
0000010 1c00 0000 dbff 4300 0500 0403 0404 0503
0000020 0404 0504 0505 0706 080c 0707 0707 0b0f
0000030 090b 110c 120f 1112 110f 1311 1c16 1317
0000040 1a14 1115 1811 1821 1d1a 1f1d 1f1f 1713
0000050 2422 1e22 1c24 1f1e ff1e 00db 0143 0505
0000060 0705 0706 080e 0e08 141e 1411 1e1e 1e1e
0000070 1e1e 1e1e 1e1e 1e1e 1e1e 1e1e 1e1e 1e1e  

最佳答案

问题出在图像文件的构造函数上:

std::ifstream   blob_file(filename.c_str());

这应该有二进制模式属性:

std::ifstream   blob_file(filename.c_str(), std::ios_base::binary);

该文件是一个 JPEG 图像,是二进制 数据。

此外,字节 65 处的十六进制转储显示 1a,这是 Windows 操作系统的文件结尾字符:
0000040 1a14 1115 1811 1821 1d1a 1f1d 1f1f 1713

修复构造函数后,MySql显示数据大小:

mysql> SELECT ID_Picture, LENGTH(Image_Data)
    -> FROM picture_image_data
    -> WHERE ID_Picture = 1;
+------------+--------------------+
| ID_Picture | LENGTH(Image_Data) |
+------------+--------------------+
|          1 |              18453 |
+------------+--------------------+
1 row in set (0.00 sec)

关于c++ - MySql Connector 准备语句只传输 64 字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3134532/

相关文章:

c++ - 返回右值引用和临时物化

C++ demo编程,混淆类实现

php - mysql使用二维数组存储数据

php - 将辅助数据输入预先存在的数据库

java - 使用带有 Oracle 数据库上的绑定(bind)变量的PreparedStatement 来触发查询

ruby-on-rails - 使用 PostgreSQL 使用 ActiveRecord 准备和执行语句

c++ - 线程安全无锁数组

c++ - 具有强异常保证的同步 STL 容器插入

mysql - 如何从查询生成器获取记录的最后插入 ID

java - java中sql的字符串参数和SELECT准备语句