Is this a effective way of executing UPDATE?

The document you expected this should be explained

Expected answer

Here is the test records

item 0 name-0, 1.2
item 1 name-1, 5.2
item 2 name-2, 6.2
item 3 name-3, 4.2
item 4 name-4, 5.2
package main

import (
    "fmt"
    "log"
    "strings"

    "gorm.io/driver/sqlite"
    // "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "gorm.io/gorm/schema"
)

type Records struct {
    RID   int `gorm:"primaryKey"`
    Name  string
    Price float64
}

type MyStrategy struct {
    schema.NamingStrategy
}

func (s MyStrategy) ColumnName(table, column string) string {
    return strings.ToLower(column)
}

func main() {
    db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{
        NamingStrategy: MyStrategy{},
    })
    // db, err := gorm.Open(mysql.New(mysql.Config{
    //  DSN: "root:root@tcp(127.0.0.1:3306)/mytest?charset=utf8&parseTime=True&loc=Local",
    // }), &gorm.Config{
    //  NamingStrategy: MyStrategy{},
    // })
    if err != nil {
        log.Fatalln(err)
    }

    r := []*Records{}
    if !db.Migrator().HasTable(r) {
        if err := db.Migrator().CreateTable(r); err != nil {
            log.Fatalln(err)
        } else {
            fmt.Println("create table ok")
            records := make([]Records, 5)
            for i := range records {
                records[i] = Records{RID: i + 1, Name: fmt.Sprintf("name-%v", i), Price: float64(i) + 1.2}
                // db.Select("id", "name", "price").Create(&records[i])
            }
            fmt.Println(&records)
            db.Create(&records)
            fmt.Println("after insert", &records)
        }
    } else { // has table, do query and then update
        gormDb := db.Find(&r)
        fmt.Println("rows =", gormDb.RowsAffected)
        rows, err := gormDb.Rows()
        if err != nil {
            log.Fatalln(err)
        }

        //query
        for rows.Next() {
            var id, name, price any

            err = rows.Scan(&id, &name, &price)
            if err != nil {
                log.Println("row scan err", err)
                continue
            }
            fmt.Printf("item %v %v, %v\n", id, name, price)
        }

        // update
        var ur []Records
        // db.Exec("update records set price=price+1 where rid in (?,?)",  1, 2)
        // raw: update records set price=price+1 where rid in (1,2)
        for _, rid := range []int{1, 2} {
            // FIXME THE CODE BELOW WORKS, but can any body give me a better solution to
            // update records set price=price+1 where rid in (1,2)
            gormDb = db.Model(&ur).Where("rid = ?", rid).Find(&ur).Updates(Records{Price: ur[0].Price + 1})

        }
        fmt.Println(ur)
        fmt.Println(gormDb.RowsAffected, gormDb.Error)
    }
}

Comment From: guest6379

// update
        var ur []Records
        // db.Exec("update records set price=price+1 where rid in (?,?)",  1, 2)
        // raw: update records set price=price+1 where rid in (1,2)
        gormDb = db.Model(&ur).Find(&ur, []int{1, 2})
        for i := range ur {
            ur[i].Price += 1
        }
        gormDb.Save(&ur)

This is my another solution of this question. Save

Comment From: a631807682

The go language feature determines that an expression cannot be assigned to float, you need to use Serializer. refer to https://github.com/go-gorm/gorm/issues/6079