MySQL 5.0.67 + Windows + VC ++ 2008的mysql_insert_id()问题

时间:2010-03-04 13:26:05

标签: mysql

在手册页上; http://dev.mysql.com/doc/refman/5.0/en/mysql-insert-id.html 据说“返回先前INSERT或UPDATE语句为AUTO_INCREMENT列生成的值。”

问题是更新后它对我没有用。

真正需要的是我正在尝试更新表中的行(使用“WHERE”条件更新),然后,如果确实更新了行,请获取完整的详细信息。 所以首先我更新,然后我需要它的id来获取SELECT语句的详细信息。

以下是显示问题的示例代码:

#define _WIN32_WINNT 0x0400
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include <stdio.h>
#include <conio.h>

#include <winsock.h>

#include "C:/Program Files (x86)/MySQL/MySQL Server 5.0/include/mysql.h"
#pragma comment(lib, "C:/Program Files (x86)/MySQL/MySQL Server 5.0/lib/opt/libmysql.lib")

void main()
{
 MYSQL *conn = mysql_init(NULL);
 if(conn == NULL)
  throw "error";
 if(mysql_real_connect(
  conn,
  "127.0.0.1",
  "user", "passwd",
  NULL,
  0,
  NULL,
  0) != conn)
  throw "error";

 int nRet = 0;

 char szInsert[] = "INSERT INTO db_transation_test.tbl_transactions SET amount=71, ses=72";
 nRet = mysql_real_query(conn, szInsert, sizeof(szInsert));
 if(nRet != 0)
 {
  printf("%s\n", mysql_error(conn));
  throw;
 }
 my_ulonglong inserted_id = mysql_insert_id(conn);

 ///////// the real issue of my post starts here /////////

 char szUpdateTemplate[] = "UPDATE db_transation_test.tbl_transactions SET amount=123 WHERE id_transaction=%lld";
 char szUpdate[1024];
 nRet = sprintf_s(szUpdate, sizeof(szUpdate), szUpdateTemplate, inserted_id);
 nRet = mysql_real_query(conn, szUpdate, nRet);
 if(nRet != 0)
 {
  printf("%s\n", mysql_error(conn));
  throw;
 }
 my_ulonglong updated_id = mysql_insert_id(conn); // returns ZERO instead of 'inserted_id' :(

 _getch();
}

在这种情况下如何使这个mysql_insert_id()函数工作,或者如何在一个statament中更新和选择?

请注意,我在此示例中插入了一行,因此它会为您创建一些行,因此您可以看到..

谢谢!

编辑: 看看我对这个问题的最新回复。我给出了更清晰的描述。

5 个答案:

答案 0 :(得分:0)

Poni,我认为 mysql_affected_rows() 是你的功能:

  执行a后,可以立即调用mysql_affected_rows()   使用mysql_query()或mysql_real_query()的语句。它返回   最后一个语句更改,删除或插入的行数if   它是UPDATE,DELETE或INSERT。对于SELECT语句,   mysql_affected_rows()的工作方式类似于mysql_num_rows()。

答案 1 :(得分:0)

如果update语句修改了自动可递增值,则mysql_insert_id将仅在update语句中返回id。据推测,如果您已经基于它进行了更新,那么您就拥有了ID,所以在更新后只需基于id进行选择。

编辑:我不是建议您在更新时修改id列,我只是说这是mysql_insert_id将返回更新查询值的唯一情况。

对评论的回应:那么你应该做的是先选择按登录名/密码获取行的id,然后按照select

结果中的行ID进行更新

答案 2 :(得分:0)

您的UPDATE语句不会导致生成自动增量的ID,因此在更新后调用mysql_insert_id是没有意义的。

正如文档所说,mysql_insert_id()适用于生成自动递增值的insert语句,或者直接调用`LAST_INSERT_ID(expr)^的update / insert语句。

您已经在插入语句后立即获取了inserted_id,您无需再次获取它。

答案 3 :(得分:0)

您的UPDATE语句不会导致生成自动增量的ID,因此在更新后调用mysql_insert_id是没有意义的。

正如文档所说,mysql_insert_id()适用于生成自动递增值的insert语句,或者直接调用`LAST_INSERT_ID(expr)^的update / insert语句。

您已经在插入语句后立即获取了inserted_id,您无需再次获取它。

编辑,你显然在问别的事情。

你有类似的东西 UPDATE db_transation_test.tbl_transactions SET amount=123 WHERE username=someone;

并且您想获取该查询更新的任何行的主键?这是你的实际问题吗?

如果是这样的话。否。运行单独的选择查询以获取该ID。

答案 4 :(得分:0)

澄清一下,忘记我最初发布的代码 - 这就是我需要的更简单的方法:

首先,我更新: 更新db_test.tbl_test SET owner_id = 55 WHERE login ='user_name'AND passwd ='password'AND owner_id = -1

然后我检查是否有任何行已更新,使用mysql_affected_rows()执行此操作。如果它是一个(不能更多因为字段“login”是唯一的)那么我想得到这行的id,而不是只做另一个SELECT。

这背后的逻辑是什么? 它将成为一个多玩家数据库商店,并且有几个服务器。 我需要以某种方式强制一个玩家一次只能登录一次。 这是通过锁定帐户来完成的; “-1”的“owner_id”表示免费游戏,如果不是,那么该玩家已经在玩。

希望现在更清楚了。