go写mysql取得自增字段值

2024-03-02 06:52

本文主要是介绍go写mysql取得自增字段值,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

场景:有多张表,依据其中一张表的自增字段取得 id 值作为对象ID,然后使用这个Id插入到其他它表中。

如下一张 MySQL 的 innodb 表 X,用 go 编写程序,不指定 a 的值,指定 b 和 c 的值,往表 X 插入数据,如果数据已经存在则执行更新操作,成功后取得该笔插入或者更新的记录对应的 a 字段的值。

create table X (a int unsigned AUTO_INCREMENT, b int, c int,PRIMARY KEY (a), UNIQUE KEY(b) 
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

非事务版本:

package mainimport ("database/sql""fmt"_ "github.com/go-sql-driver/mysql"
)func main() {db, err := sql.Open("mysql", "user:password@tcp(localhost:3306)/dbname")if err != nil {panic(err)}defer db.Close()// 插入或更新记录query := `INSERT INTO X (b, c) VALUES (?, ?)ON DUPLICATE KEY UPDATE c = VALUES(c), a = LAST_INSERT_ID(a)`result, err := db.Exec(query, "value1", "value2")if err != nil {panic(err)}// 获取自增IDlastInsertID, err := result.LastInsertId()if err != nil {panic(err)}fmt.Printf("LastInsertID: %d\n", lastInsertID)
}

非事务版本不能保持 a 值的连续性。

事务版本:

package mainimport ("database/sql""fmt""sync"_ "github.com/go-sql-driver/mysql"
)func upsertRecord(db *sql.DB, b, c int) (int, error) {// 开始事务tx, err := db.Begin()if err != nil {return 0, err}defer tx.Rollback()// 尝试查找记录var id interr = tx.QueryRow("SELECT a FROM X WHERE b = ?", b).Scan(&id)if err != nil {if err == sql.ErrNoRows {// 记录不存在,插入新的记录result, err := tx.Exec("INSERT INTO X (b, c) VALUES (?, ?)", b, c)if err != nil {return 0, err}lastInsertID, err := result.LastInsertId()if err != nil {return 0, err}id = int(lastInsertID)} else {// 其他错误return 0, err}} else {// 记录存在,更新记录_, err = tx.Exec("UPDATE X SET c = ? WHERE a = ?", c, id)if err != nil {return 0, err}}// 提交事务err = tx.Commit()if err != nil {return 0, err}return id, nil
}func main() {db, err := sql.Open("mysql", "dswrite:ds#582701@tcp(9.134.177.242:3306)/dsdb")if err != nil {panic(err)}defer db.Close()var wg sync.WaitGroupfor i := 0; i < 10; i++ {wg.Add(1)go func(i int) {defer wg.Done()id, err := upsertRecord(db, 20+i, 100+i)if err != nil {fmt.Printf("Error: %v\n", err)} else {fmt.Printf("ID: %d\n", id)}}(i)}wg.Wait()
}

该版本可以保持 a 值的连续性。实际可以再优化,去掉 select,先 insert 或者 update 即可。

这篇关于go写mysql取得自增字段值的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/765273

相关文章

MySQL分表自动化创建的实现方案

《MySQL分表自动化创建的实现方案》在数据库应用场景中,随着数据量的不断增长,单表存储数据可能会面临性能瓶颈,例如查询、插入、更新等操作的效率会逐渐降低,分表是一种有效的优化策略,它将数据分散存储在... 目录一、项目目的二、实现过程(一)mysql 事件调度器结合存储过程方式1. 开启事件调度器2. 创

SQL Server使用SELECT INTO实现表备份的代码示例

《SQLServer使用SELECTINTO实现表备份的代码示例》在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误,在SQLServer中,可以使用SELECTINT... 在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误。在 SQL Server 中,可以使用 SE

基于Go语言实现一个压测工具

《基于Go语言实现一个压测工具》这篇文章主要为大家详细介绍了基于Go语言实现一个简单的压测工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录整体架构通用数据处理模块Http请求响应数据处理Curl参数解析处理客户端模块Http客户端处理Grpc客户端处理Websocket客户端

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

mysql外键创建不成功/失效如何处理

《mysql外键创建不成功/失效如何处理》文章介绍了在MySQL5.5.40版本中,创建带有外键约束的`stu`和`grade`表时遇到的问题,发现`grade`表的`id`字段没有随着`studen... 当前mysql版本:SELECT VERSION();结果为:5.5.40。在复习mysql外键约

SQL注入漏洞扫描之sqlmap详解

《SQL注入漏洞扫描之sqlmap详解》SQLMap是一款自动执行SQL注入的审计工具,支持多种SQL注入技术,包括布尔型盲注、时间型盲注、报错型注入、联合查询注入和堆叠查询注入... 目录what支持类型how---less-1为例1.检测网站是否存在sql注入漏洞的注入点2.列举可用数据库3.列举数据库

Mysql虚拟列的使用场景

《Mysql虚拟列的使用场景》MySQL虚拟列是一种在查询时动态生成的特殊列,它不占用存储空间,可以提高查询效率和数据处理便利性,本文给大家介绍Mysql虚拟列的相关知识,感兴趣的朋友一起看看吧... 目录1. 介绍mysql虚拟列1.1 定义和作用1.2 虚拟列与普通列的区别2. MySQL虚拟列的类型2

mysql数据库分区的使用

《mysql数据库分区的使用》MySQL分区技术通过将大表分割成多个较小片段,提高查询性能、管理效率和数据存储效率,本文就来介绍一下mysql数据库分区的使用,感兴趣的可以了解一下... 目录【一】分区的基本概念【1】物理存储与逻辑分割【2】查询性能提升【3】数据管理与维护【4】扩展性与并行处理【二】分区的

MySQL中时区参数time_zone解读

《MySQL中时区参数time_zone解读》MySQL时区参数time_zone用于控制系统函数和字段的DEFAULTCURRENT_TIMESTAMP属性,修改时区可能会影响timestamp类型... 目录前言1.时区参数影响2.如何设置3.字段类型选择总结前言mysql 时区参数 time_zon

Python MySQL如何通过Binlog获取变更记录恢复数据

《PythonMySQL如何通过Binlog获取变更记录恢复数据》本文介绍了如何使用Python和pymysqlreplication库通过MySQL的二进制日志(Binlog)获取数据库的变更记录... 目录python mysql通过Binlog获取变更记录恢复数据1.安装pymysqlreplicat