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
更好的做法是使用存储过程,并在该存储过程中返回最后的ID
更多关于Golang使用database/sql包连接Oracle时LastInsertId返回0的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
result.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 环境中可靠地获取插入的主键值。

