我知道一次插入多个数据效率更高:

INSERT INTO test(n1, n2, n3) 
VALUES(v1, v2, v3),(v4, v5, v6),(v7, v8, v9);

在golang 怎么做呢?

data := []map[string]string{
   {"v1":"1", "v2":"1", "v3":"1"},
   {"v1":"2", "v2":"2", "v3":"2"},
   {"v1":"3", "v2":"3", "v3":"3"},
}
//I do not want to do it
for _, v := range data {
    sqlStr := "INSERT INTO test(n1, n2, n3) VALUES(?, ?, ?)"
    stmt, _ := db.Prepare(sqlStr)
    res, _ := stmt.Exec(v["v1"], v["v2"], v["v3"])
}

用细绳拼接,但不太好.db.prepare更安全,对吗?

sqlStr := "INSERT INTO test(n1, n2, n3) VALUES"
for k, v := range data {
    if k == 0 {
        sqlStr += fmt.Sprintf("(%v, %v, %v)", v["v1"], v["v2"], v["v3"])
    } else {
        sqlStr += fmt.Sprintf(",(%v, %v, %v)", v["v1"], v["v2"], v["v3"])
    } 
}
res, _ := db.Exec(sqlStr)

我需要一个功能,更安全和有效的插入多个数据一次.

推荐答案

为什么不是这样?(此处未经测试,因此可能存在语法错误):

sqlStr := "INSERT INTO test(n1, n2, n3) VALUES "
vals := []interface{}{}

for _, row := range data {
    sqlStr += "(?, ?, ?),"
    vals = append(vals, row["v1"], row["v2"], row["v3"])
}
//trim the last ,
sqlStr = sqlStr[0:len(sqlStr)-1]
//prepare the statement
stmt, _ := db.Prepare(sqlStr)

//format all vals at once
res, _ := stmt.Exec(vals...)

Go相关问答推荐

如何模拟嵌入. FS?

CGO Linux到Windows交叉编译中的未知类型名称

如何预编译Golang标准库?

如何用';贪婪原则';正确地

如何在 Go 服务中导入 monorepo 中的包?

从单词中删除特殊字符

使用 Go 解组 SOAP 消息

Go 的垃圾收集器在使用时删除 ZeroMQ 套接字

Golang 中具体类型的错误片段

有没有办法约束(通用)类型参数?

Go Colly 如何找到请求的元素?

速率限制特定端点

Golang 构建多平台问题

Golang - 将 [8] 布尔转换为字节

在 Raspberry Pi4 上下载 Go Mod

使用反射在 struct 内迭代切片 struct

递归数据 struct 解组在 Go Lang Protobuf 中给出错误无法解析无效的线格式数据

行之间的模板交替设计

为什么在 goroutine 中声明时,benbjohnson/clock 模拟计时器不执行?

Go 错误:Is() 和 As() 声称是递归的,是否有任何类型实现错误接口并支持这种递归 - 无错误?