【问题标题】:go mysql LAST_INSERT_ID() returns 0go mysql LAST_INSERT_ID() 返回 0
【发布时间】:2022-01-22 00:56:17
【问题描述】:

我有这个 MySQL 数据库,我需要在其中使用 go 程序添加记录,并且需要检索最后添加的记录的 id,以将 id 添加到另一个表中。

当我在 MySQL Workbench 中运行 insert INSERT INTO table1 values("test",1); SELECT LAST_INSERT_ID() 时,它返回最后一个 id,它是自动递增的,没有问题。

如果我运行我的 go 代码,它总是打印 0。代码:


    _, err := db_client.DBClient.Query("insert into table1 values(?,?)", name, 1)
    var id string
    err = db_client.DBClient.QueryRow("SELECT LAST_INSERT_ID()").Scan(&id)
    if err != nil {
        panic(err.Error())
    }
    fmt.Println("id: ", id)

我尝试了这种变体来进一步缩小问题范围:err = db_client.DBClient.QueryRow("SELECT id from table1 where name=\"pleasejustwork\";").Scan(&id),效果很好; go 返回实际的 id。

为什么它不能与 LAST_INSERT_ID() 一起使用?

我是围棋新手,所以如果我犯了导致此错误的愚蠢围棋错误,请不要对我太苛刻:D

提前谢谢你。

【问题讨论】:

  • 为什么它不能与 LAST_INSERT_ID() 一起工作? 99% 的一些中间查询被隐藏发送到 MySQL,或者第二个查询在另一个连接中执行。在单个事务中执行两个查询。
  • 好的,但是你将如何解决这个问题?我需要查询的 id,我想我不能在一个函数调用中放置 2 个查询
  • 使用Query并丢弃,即分配给_,主返回值,将导致资源泄漏。对于不返回任何行的查询,您应该使用Exec 方法。 Exec 方法还返回一个 sql.Result 值,如果由您使用的第 3 方驱动程序实现,它将通过 LastInsertedId 方法为您提供最后插入的 id。
  • 另外请注意,Go 中的数据库句柄是一个 连接,很可能两个单独的查询是使用池中的两个不同连接执行的。并且,就 mysql 而言,由 AUTO_INCREMENT 生成的ID每个连接的基础上 在服务器中维护。这意味着函数 LAST_INSERT_ID 返回的值是为使用 same 连接执行的最近插入语句生成的第一个 AUTO_INCREMENT 值。

标签: mysql sql go last-insert-id


【解决方案1】:

MySQL 协议在其对INSERT 语句的响应中返回LAST_INSERT_ID() 值。而且,golang 驱动程序公开了该返回值。因此,您不需要额外的往返行程即可获得它。这些 ID 值通常是无符号的 64 位整数。

试试这样的。

    res, err := db_client.DBClient.Exec("insert into table1 values(?,?)", name, 1)
     if err != nil {
        panic (err.Error())
    }
    id, err := res.LastInsertId()
    if err != nil {
        panic (err.Error())
    }
    fmt.Println("id: ", id)

我承认我不确定您的代码为什么不起作用。每当您成功发出单行 INSERT 语句时,同一数据库连接上的下一条语句总是可以访问有用的LAST_INSERT_ID() 值。无论您是否使用显式事务都是如此。

但是如果你的INSERT不成功,你必须把最后插入的ID值当成不可预测的。(这是“垃圾”、垃圾、垃圾、basura等的技术术语)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-20
    • 2012-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多