c++ - MySQL C++ 连接器 : what is the correct way to use SetBlob() to set multiple blob data in a query?

标签 c++ mysql c++11

我在 stackexchange db admin 上问了同样的问题,这似乎是该问题的正确位置,但问题是没有人查看该问题。所以我再次在这里发布同样的问题:

我正在研究Mysql表插入。建表语句如下:

CREATE TABLE files_table (fid INT NOT NULL AUTO_INCREMENT, idx TINYBLOB, head TINYBLOB, size BLOB, PRIMARY KEY(fid));

我可以手动插入记录

mysql> select * from files_table order by fid asc;
+-----+------+------+------------+
| fid | idx  | head | size       |
+-----+------+------+------------+
|   1 | 1    | 1    | 1          |
+-----+------+------+------------+

但是当我使用连接器通过 C++ 连接器添加下一个值时:

class StreamBufferData : public std::streambuf
{
public:
    StreamBufferData(const char *in_data, size_t in_size)
    {
        setg(in_data, in_data, in_data + in_size);
    }
};

enum{QUERY_SIZE=256;}
char ins[QUERY_SIZE];

strcpy(ins, "INSERT INTO files_table (idx, head, size) VALUES (?,?,?)");

try
{
    std::unique_ptr<sql::PreparedStatement> statement(ptr_connection->prepareStatement(ins));

    char test_data[2] = "0";
    StreamBufferData buffer0(test_data, 2);
    std::istream test_s0(&buffer0);
    statement->setBlob(1, &test_s0);

    strcpy(test_data, "1");
    StreamBufferData buffer1(test_data, 2);
    std::istream test_s1(&buffer1);
    statement->setBlob(2, &test_s1);

    strcpy(test_data, "2");
    StreamBufferData buffer2(test_data, 2);
    std::istream test_s2(&buffer2);
    statement->setBlob(3, &test_s2);

    statement->executeUpdate();
}
catch(sql::SQLException &e)
{
    std::cout << e.what() << ‘\n’; 
    return;
}

结果是:

+-----+------+------+------------+
| fid | idx  | head | size       |
+-----+------+------+------------+
|   1 | 1    | 1    | 1          |
|   2 | 2    | 2    | 2          |
+-----+------+------+------------+

只有最后一个值被正确插入到表中。我的问题是:用户 msql::PreparedStatement::setBlob() 在查询中设置多个 blob 的正确方法是什么?

[环境]
Ubuntu 16.04.2
MySQL 5.7
MySQL连接器版本:7.1.1.7
提升1.58.0
g++ 5.4.0

感谢您的帮助

最佳答案

不同的std::istream对象指向由test_data分配的同一个缓冲区。我认为 istream 对象会复制 char 数组中的值。事实是,事实并非如此。

还值得指出的是,如果 std::istream 对象在 statements->executeUpdate() 执行之前被销毁。最后一个流对象将填充到表的第一列中,这在我的机器(Ubuntu 16.04.2 LTS)上可能是未定义的行为。它看起来像:

+-----+------+------+------------+
| fid | idx  | head | size       |
+-----+------+------+------------+
|   1 | 1    | 1    | 1          |
|   2 | 2    |      |            |
+-----+------+------+------------+

因此,如果表有像上表一样的奇怪结果,请检查代码以确保 std::stream、StreamBufferData 和指向缓冲区的指针仍然有效,直到执行了 statements->executeUpdate()。

关于c++ - MySQL C++ 连接器 : what is the correct way to use SetBlob() to set multiple blob data in a query?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45874074/

相关文章:

c++ - 如何解决这个编译错误

php - 准备好的语句: column cannot be null

mysql - 将 Heroku 应用程序与 Amazon RDS 实例连接时出现问题

c++ - 返回值的转发。需要 std::forward 吗?

c++ - 为满足条件的类专门化 `std::hash`

c++ - GDB 跳过了我的代码!

c++ - 使用 dynamic_cast 的奇怪行为

c++ - SDL2 图像到屏幕问题

javascript - 数据通过 websocketpp 返回为 json,但通过 messagepack 返回为 Blob

mysql - Django ORM key 错误并丢失 MySql 连接