// Update columns to new value on `id` conflict
DB.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}}, // key colume
DoUpdates: clause.AssignmentColumns([]string{"name", "age"}), // column needed to be updated
}).Create(&users)
// MERGE INTO "users" USING *** WHEN NOT MATCHED THEN INSERT *** WHEN MATCHED THEN UPDATE SET "name"="excluded"."name"; SQL Server
// INSERT INTO "users" *** ON CONFLICT ("id") DO UPDATE SET "name"="excluded"."name", "age"="excluded"."age"; PostgreSQL
// INSERT INTO `users` *** ON DUPLICATE KEY UPDATE `name`=VALUES(name),`age=VALUES(age); MySQL
对于 gorm 1.9.x 或以下版本,先更新更有效,然后在不存在时插入。
// update only set name=nick
if err := db.Model(&newUser).Where("id = ?", 3333).Update("name", "nick").Error; err != nil {
// always handle error like this, cause errors maybe happened when connection failed or something.
// record not found...
if gorm.IsRecordNotFoundError(err){
db.Create(&newUser) // create new record from newUser
}
}
更新2020.10.09
感谢 @vaelin
从 1.20.x 开始,GORM 为不同的数据库提供兼容的 Upsert 支持( Upsert-On-Conflict )
对于 gorm 1.9.x 或以下版本,先更新更有效,然后在不存在时插入。
FirstOrInit
和FirstOrCreate
是不同的。如果数据库中没有匹配记录,FirstOrInit
将初始化结构但不创建记录,FirstOrCreate
将创建一个记录并查询该记录以构建。