Golang使用database/sql包连接Oracle时LastInsertId返回0的问题

Golang使用database/sql包连接Oracle时LastInsertId返回0的问题 我正在使用 database/sql 包配合 Oracle 驱动程序(“gopkg.in/rana/ora.v4”),当我插入数据时,LastInsertId 方法返回 0,但数据已成功插入。 附上代码:

import (
    "database/sql"
    "fmt"
    "os"
    "strconv"
    "strings"
    "sync"

    _ "gopkg.in/rana/ora.v4"
)

func main() {
    conn, err = sql.Open("ora", username+"/"+password+"@"+host+":"+port+"/"+sid)
    query := "INSERT INTO Table (C2) VALUES (:C2)"
    result, err := conn.Exec(query, "Test")
    if err != nil {
        panic(err)
    }
    lastId := result.LastInsertId() // 返回 0
    fmt.Println(lastId)
}

请告诉我为什么会发生这种情况?


更多关于Golang使用database/sql包连接Oracle时LastInsertId返回0的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

更好的做法是使用存储过程,并在该存储过程中返回最后的ID

更多关于Golang使用database/sql包连接Oracle时LastInsertId返回0的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


result.LastInsertId() 应该返回一个错误作为第二个值,请检查它是否非空。并非所有数据库都支持此功能。

由于您在粘贴的代码中没有使用第二个值,我甚至不确定它是否能编译通过,而且我无法测试,因为我在移动设备上。

编辑

请同时阅读 https://github.com/rana/ora#lastinsertid

在 Oracle 数据库中,LastInsertId() 方法通常无法正常工作,因为 Oracle 不支持标准的自动增量字段,而是使用序列(Sequence)和触发器(Trigger)来生成主键值。database/sql 包的 LastInsertId() 方法依赖于数据库驱动程序的实现,而 Oracle 驱动程序(如 rana/ora)可能未实现此功能,导致始终返回 0。

要解决这个问题,您需要在插入数据时显式使用序列来生成主键,并在插入后通过查询获取该值。以下是修改后的代码示例:

import (
    "database/sql"
    "fmt"
    "log"

    _ "gopkg.in/rana/ora.v4"
)

func main() {
    // 假设您的表有一个名为 ID 的主键列,使用序列 SEQ_TABLE_ID 生成值
    conn, err := sql.Open("ora", "username/password@host:port/sid")
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    // 使用序列插入数据,并返回生成的主键值
    query := "INSERT INTO Table (ID, C2) VALUES (SEQ_TABLE_ID.NEXTVAL, :C2) RETURNING ID INTO :id"
    var lastId int64
    _, err = conn.Exec(query, sql.Named("C2", "Test"), sql.Named("id", sql.Out{Dest: &lastId}))
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Last inserted ID: %d\n", lastId)
}

在这个示例中:

  • 假设表 Table 有一个主键列 ID,通过序列 SEQ_TABLE_ID 生成值。
  • 使用 RETURNING ... INTO 子句在插入时返回生成的主键值,并通过 sql.Out 参数捕获它。
  • 插入后,lastId 变量将包含正确的主键值。

如果您的表结构不同,请根据实际情况调整序列名和列名。这种方法确保了在 Oracle 环境中可靠地获取插入的主键值。

回到顶部