使用预准备语句后,SELECT LAST_INSERT_ID()返回0

时间:2011-02-26 01:49:39

标签: c++ mysql prepared-statement mysqldump

我使用MySQL和准备好的语句来插入BLOB记录(jpeg图像)。执行准备好的语句后,我发出SELECT LAST_INSERT_ID()并返回0.

在我的代码中,我在执行命令之后放置一个断点,在MySQL命令(监视器)窗口中,我发出SELECT LAST_INSERT_ID()并返回零。

在MySQL命令(监视器)窗口中,我发出一个SQL语句来选择所有ID,最后一个(仅)插入的ID是1(一个)。

我正在使用:

  • 服务器版本:5.1.46-community MySQL社区服务器(GPL)
  • Visual Studio 2008,版本9.
  • MySQL Connector C ++ 1.0.5

我的表格描述:

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

使用MySQL监视器的结果:

mysql> select ID_Image_Data
    -> from picture_image_data;
+---------------+
| ID_Image_Data |
+---------------+
|             1 |
+---------------+
1 row in set (0.00 sec)

mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                0 |
+------------------+
1 row in set (0.00 sec)

准备好的声明:

INSERT INTO Picture_Image_Data
(ID_Image_Data, Image_Data)
VALUES
    (?,
       ?);

上面的结果显示ID_Image_Data字段为1,但LAST_INSERT_ID为零。该表是在执行此语句之前创建的,因此这是表中唯一的记录。


编辑:

我将ID字段设置为零,将下一个字段设置为C ++ std::istream *。根据{{​​3}}:

如果将行的AUTO_INCREMENT列设置为非“魔术”值(即非NULL且不为0的值),则不会更改LAST_INSERT_ID()的值)。

由于预准备语句中的ID值为0,因此LAST_INSERT_ID()应返回1.


我是否需要为获取LAST_INSERT_ID制作一个准备好的语句?

{搜索网络显示使用自定义MySQL API,但使用PHP和更进一步的评论说它需要另一个连接。)

3 个答案:

答案 0 :(得分:5)

LAST_INSERT_ID仅适用于在auto_increment字段上创建的自动生成的主键。在您的情况下,看起来您显式提供了id,因此未设置最后一个插入ID。

这是明确的:

mysql> insert into test (id, name) VALUES (5, 'test 2');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                0 |
+------------------+
1 row in set (0.00 sec)

这是隐含的:

mysql> insert into test (name) values ('test');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                3 |
+------------------+
1 row in set (0.00 sec)

答案 1 :(得分:1)

看起来问题与MySQL C ++连接器有关。

  1. LAST_INSERT_ID()返回0时 ID字段为空,显式 插入
  2. LAST_INSERT_ID()返回0时 未指定ID字段, 隐含插入。
  3. 我尝试从命令行(监视器)插入BLOB(JPEG图像),它可以工作:

    mysql> describe picture_image_data;
    +---------------+------------------+------+-----+---------+----------------+
    | Field         | Type             | Null | Key | Default | Extra          |
    +---------------+------------------+------+-----+---------+----------------+
    | ID_Image_Data | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
    | Image_Data    | mediumblob       | YES  |     | NULL    |                |
    +---------------+------------------+------+-----+---------+----------------+
    2 rows in set (0.03 sec)
    mysql> PREPARE blob_stmt
        ->     FROM 'INSERT INTO picture_image_data (ID_Image_Data, Image_Data) VALUES (?, LOAD_FILE(?))';
    Query OK, 0 rows affected (0.02 sec)
    Statement prepared
    
    mysql> SET @id = 0;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SET @c = 'KY_hot_brown_picture.jpg';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> EXECUTE blob_stmt USING @id, @c;
    Query OK, 1 row affected (0.15 sec)
    
    mysql> SELECT LAST_INSERT_ID();
    +------------------+
    | LAST_INSERT_ID() |
    +------------------+
    |                2 |
    +------------------+
    
    1 row in set (0.00 sec)
    

    目前,解决方法是使用SQL语句使用预准备语句而不是MySQL C ++ Connector API插入BLOB。

答案 2 :(得分:0)

您不能指望在mysql命令行客户端上发出SELECT LAST_INSERT_ID(),以便为您提供在C ++代码中生成的最后一个插入值。

LAST_INSERT_ID()为您提供给定连接上的最后一个自动生成的ID。显然你的C ++程序和mysql客户端使用2个不同的连接到mysql服务器。

(也应该在INSERT之后使用LAST_INSERT_ID(),在INSERT和SELECTLAST_INSERT_ID()中没有其他SQL语句