golang grom 实现 INSERT...ON DUPLICATE KEY UPDATE

内容来自对 chatgpt 的咨询

前言(INSERT...ON DUPLICATE KEY UPDATE 介绍)

当你在MySQL中插入数据,如果唯一键发生冲突,可以使用 INSERT...ON DUPLICATE KEY UPDATE 语句实现插入和更新操作。其基本语法如下:

INSERT INTO table (col1, col2, ...colN)
VALUES (value1, value2, ...valueN)
ON DUPLICATE KEY UPDATE
col1 = value1, col2 = value2, ...colN = valueN;

这条语句的逻辑是:如果插入的记录与表中现有记录的唯一索引或主键冲突,那么就执行 UPDATE 操作。如果没有冲突,那么就执行 INSERT 操作。

例如,表users有唯一键user_id,现在想插入或更新一条 user_id=1 的记录:

INSERT INTO users (user_id, user_name, user_email)
VALUES (1, 'John', 'john@example.com')
ON DUPLICATE KEY UPDATE
user_name='John', user_email = 'john@example.com';

在以上的例子中,如果 user_id=1 的这条记录已经存在,在执行此语句后,user_name 和 user_email 会被更新为新的值。如果 user_id=1 的记录不存在,那么这个语句就会新插入一条记录。

注意

在 ON DUPLICATE KEY UPDATE 后面的赋值表达式中,你不能使用 VALUES(col) 获取插入语句中的值,因为它可能被认为是值的字面量而不是列表的值。你应该直接使用要输入的值或者变量。

在 grom 中使用 mysql 的这种语法效果

可以使用GORM的 Exec() 函数,执行自定义的SQL语句来实现MySQL的 INSERT...ON DUPLICATE KEY UPDATE 功能。下面这段代码段会尝试插入users数组中的每个用户,并在发生主键冲突的情况下,更新冲突数据的user_name和user_email字段。需要注意的是,VALUES(user_name), VALUES(user_email)中的VALUES函数能引用到插入时的真实数据,占位符会被替换成真实数据。

users := []User{
    {UserID: 1, UserName: "John1", UserEmail: "john1@example.com"},
    {UserID: 2, UserName: "John2", UserEmail: "john2@example.com"},
    {UserID: 3, UserName: "John3", UserEmail: "john3@example.com"},
}

valueStrings := []string{}
valueArgs := []interface{}{}

// 构造插入语句和冲突时的更新语句
for _, user := range users {
    valueStrings = append(valueStrings, "(?, ?, ?)")
    valueArgs = append(valueArgs, user.UserID)
    valueArgs = append(valueArgs, user.UserName)
    valueArgs = append(valueArgs, user.UserEmail)
}

stmt := fmt.Sprintf("INSERT INTO users (user_id, user_name, user_email) VALUES %s"+
    "ON DUPLICATE KEY UPDATE user_name=VALUES(user_name), user_email=VALUES(user_email)",
    strings.Join(valueStrings, ","))

db.Exec(stmt, valueArgs...)

注意点

  • 注意使用这种方法时要确保你对用户的数据有100%的信任,或者已经进行了相应的清理,以防止SQL注入攻击。

  • 在执行 SQL 语句之前,需要检查 users 数组是否为空。如果 users 长度为0,则需要跳过构造和执行 SQL 语句的步骤。因为如果 users 数组为空,那么在构造 SQL 插入语句的过程中,valueStrings 和 valueArgs 切片都将保持为空,这意味着 最终拼接后的 sql 长这样:INSERT INTO users VALUES ON DUPLICATE KEY UPDATE,可以看出来在 "VALUES" 关键字前没有标明字段名,关键词后并未提供任何数据,从而导致 SQL 语法错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值