Golang中如何执行多条更新语句
Golang中如何执行多条更新语句 如何使用Golang执行多个更新语句,例如:
UPDATE $userName SET P1 = '$p1MON' WHERE day = 'MON1';
UPDATE $userName SET P1 = '$p1TUE' WHERE day = 'TUE1';
UPDATE $userName SET P1 = '$p1WED' WHERE day = 'WED1'
我知道,我们可以使用 db.prepare 来处理多个插入语句,但对于更新语句感到疑惑。
我也遇到了同样的问题。幸运的是看到了你的帖子,感谢分享。你真是太棒了。 
更多关于Golang中如何执行多条更新语句的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
uvaaram:
我们如何使用 Golang 执行多个像这样的更新语句?
使用原生 SQL
UPDATE users SET username =
CASE day
WHEN 'MON1' THEN '$p1MON'
WHEN 'TUE1' THEN '$p1TUE'
WHEN 'WED1' THEN '$p1WED'
ELSE '?' END;
DB Fiddle - SQL Database Playground
一个用于测试、调试和分享 SQL 片段的在线 SQL 数据库演练场。
你好 Kiran,
标准库并未提供ORM的高级功能或驱动库。你可以使用驱动库提供的批量更新功能。
我不知道你目前在使用哪种数据库,但我假设是PostgreSQL。通过驱动库,你可以轻松地进行批量更新。
我还找到了用于生成批量更新的原始SQL语句,如果你不希望使用驱动库,可以在 database/sql 中使用它。
补充说明:db.prepare 并不会让你直接拥有批量插入功能。它的唯一目的是为你的数据库开启一个事务。
请参考以下示例: https://pkg.go.dev/github.com/go-pg/pg#example-DB-Update-BulkUpdate
db := modelDB()
book1 := &Book{
Id: 1,
Title: "updated book 1",
UpdatedAt: time.Now(),
}
book2 := &Book{
Id: 2,
Title: "updated book 2",
UpdatedAt: time.Now(),
}
// UPDATE "books" AS "book"
// SET "title" = _data."title"
// FROM (VALUES ('updated book 1', 1), ('updated book 2', 2)) AS _data("title", "id")
// WHERE "book"."id" = _data."id"
_, err := db.Model(book1, book2).Column("title", "updated_at").Update()
if err != nil {
panic(err)
}
var books []Book
err = db.Model(&books).Order("id").Select()
if err != nil {
panic(err)
}
fmt.Println(books)
在Golang中执行多条更新语句,可以使用事务(Transaction)来确保原子性,或者使用预处理语句(Prepared Statement)批量执行。以下是两种方法的示例代码:
方法一:使用事务(推荐)
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/dbname")
if err != nil {
panic(err)
}
defer db.Close()
userName := "users"
updates := []struct {
day string
p1 string
}{
{"MON1", "value1"},
{"TUE1", "value2"},
{"WED1", "value3"},
}
tx, err := db.Begin()
if err != nil {
panic(err)
}
for _, update := range updates {
query := fmt.Sprintf("UPDATE %s SET P1 = ? WHERE day = ?", userName)
_, err := tx.Exec(query, update.p1, update.day)
if err != nil {
tx.Rollback()
panic(err)
}
}
err = tx.Commit()
if err != nil {
panic(err)
}
}
方法二:使用预处理语句批量执行
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/dbname")
if err != nil {
panic(err)
}
defer db.Close()
userName := "users"
query := fmt.Sprintf("UPDATE %s SET P1 = ? WHERE day = ?", userName)
stmt, err := db.Prepare(query)
if err != nil {
panic(err)
}
defer stmt.Close()
updates := []struct {
day string
p1 string
}{
{"MON1", "value1"},
{"TUE1", "value2"},
{"WED1", "value3"},
}
for _, update := range updates {
_, err := stmt.Exec(update.p1, update.day)
if err != nil {
panic(err)
}
}
}
方法三:使用SQL语句拼接(注意SQL注入风险)
package main
import (
"database/sql"
"fmt"
"strings"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/dbname")
if err != nil {
panic(err)
}
defer db.Close()
userName := "users"
updates := map[string]string{
"MON1": "value1",
"TUE1": "value2",
"WED1": "value3",
}
var queries []string
for day, p1 := range updates {
query := fmt.Sprintf("UPDATE %s SET P1 = '%s' WHERE day = '%s'", userName, p1, day)
queries = append(queries, query)
}
fullQuery := strings.Join(queries, ";")
_, err = db.Exec(fullQuery)
if err != nil {
panic(err)
}
}
第一种方法使用事务,确保所有更新要么全部成功,要么全部失败。第二种方法使用预处理语句,可以重复使用SQL模板。第三种方法直接拼接SQL语句,但需要注意防止SQL注入,建议使用参数化查询。

