英文:
Golang Join array interface
问题
我尝试创建批量插入。我使用gorm github.com/jinzhu/gorm
import (
"fmt"
dB "github.com/edwinlab/api/repositories"
)
func Update() error {
tx := dB.GetWriteDB().Begin()
sqlStr := "INSERT INTO city(code, name) VALUES (?, ?),(?, ?)"
vals := []interface{}{}
vals = append(vals, "XX1", "Jakarta")
vals = append(vals, "XX2", "Bandung")
tx.Exec(sqlStr, vals)
tx.Commit()
return nil
}
但是我遇到了一个错误:
Error 1136: Column count doesn't match value count at row 1,因为我返回了错误的查询
INSERT INTO city(code, name) VALUES ('XX1','Jakarta','XX2','Bandung', %!v(MISSING)),(%!v(MISSING), %!v(MISSING))
如果我使用手动查询,它可以工作:
tx.Exec(sqlStr, "XX1", "Jakarta", "XX2", "Bandung")
它将生成:
INSERT INTO city(code, name) VALUES ('XX1', 'Jakarta'),('XX2', 'Bandung')
问题是如何使数组接口生成像"XX1", "Jakarta", ...
这样的字符串。
谢谢帮助。
英文:
I try to create bulk insert. I use gorm github.com/jinzhu/gorm
import (
"fmt"
dB "github.com/edwinlab/api/repositories"
)
func Update() error {
tx := dB.GetWriteDB().Begin()
sqlStr := "INSERT INTO city(code, name) VALUES (?, ?),(?, ?)"
vals := []interface{}{}
vals = append(vals, "XX1", "Jakarta")
vals = append(vals, "XX2", "Bandung")
tx.Exec(sqlStr, vals)
tx.Commit()
return nil
}
But I got an error:
> Error 1136: Column count doesn't match value count at row 1 becuse i return wrong query
>
> INSERT INTO city(code, name) VALUES ('XX1','Jakarta','XX2','Bandung', %!v(MISSING)),(%!v(MISSING), %!v(MISSING))
If I use manual query it works:
tx.Exec(sqlStr, "XX1", "Jakarta", "XX2", "Bandung")
It will generate:
INSERT INTO city(code, name) VALUES ('XX1', 'Jakarta'),('XX2', 'Bandung')
The problem is how to make array interface to generate string like "XX1", "Jakarta", ...
Thanks for help.
答案1
得分: 5
如果你想将切片的元素作为可变参数传递给一个函数,你需要使用...
告诉编译器你想逐个传递所有元素,而不是将切片作为单个参数传递。所以你可以这样做:
tx.Exec(sqlStr, vals...)
这在规范中有详细说明:将参数传递给...参数。
Tx.Exec()
的签名是:
func (tx *Tx) Exec(query string, args ...interface{}) (Result, error)
所以你需要传递vals...
。同时不要忘记检查返回的错误,例如:
res, err := tx.Exec(sqlStr, vals...)
if err != nil {
// 处理错误
}
英文:
If you want to pass elements of a slice to a function with variadic parameter, you have to use ...
to tell the compiler you want to pass all elements individually and not pass the slice value as a single argument, so simply do:
tx.Exec(sqlStr, vals...)
This is detailed in the spec: Passing arguments to ... parameters.
Tx.Exec()
has the signature of:
func (tx *Tx) Exec(query string, args ...interface{}) (Result, error)
So you have to pass vals...
. Also don't forget to check returned error, e.g.:
res, err := tx.Exec(sqlStr, vals...)
if err != nil {
// handle error
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论