如何解决如何在postgres中通过sqlx批量插入并获取结果
插入一条记录并得到如下结果很容易:
s := "INSERT INTO quiz_answer_details (quiz_answer_id,question_id,type,choices,content) VALUES ($1,$2,$3,$4,$5) RETURNING *"
d,err := fromQuizAnswerDetail(in)
if err != nil {
return nil,err
}
var out quizAnswerDetail
if err := m.core.GetContextOnMaster(ctx,&out,s,d.QuizAnswerID,d.QuestionID,d.Type,d.Choices,d.Content); err != nil {
return nil,err
}
但是如何进行批量插入并获得所有结果?我尝试了几种方法,但一无所获。
这是我认为应该工作但它没有
s := "INSERT INTO quiz_answer_details (quiz_answer_id,$5) RETURNING *"
data,err := fromQuizAnswerDetails(ins)
if err != nil {
return nil,err
}
dbs,_ := m.core.GetAllMasters()
stmt,err := dbs[0].PreparexContext(ctx,s)
if err != nil {
return nil,err
}
var out quizAnswerDetails
for _,d := range data {
var detail quizAnswerDetail
if err := stmt.GetContext(ctx,&detail,pq.Array(d.Choices),d.Content); err != nil {
return nil,err
}
out = append(out,detail)
}
return out.to()
错误信息是这样的:
quiz-answer_test.go:35: driver: skip fast-path; continue as if unimplemented
提前致谢
解决方法
我无法专门为您提供 sqlx
的帮助,因为我不熟悉该包,但是在使用标准库的 database/sql
包时,可以执行如下所示的批量插入。
如果需要编写的不同批处理查询的数量很多,或者如果项目处于设计阶段并且数据库架构的更改比人们希望的更频繁,则它非常冗长并且可能变得难以维护。在这些情况下,下面的示例可以使用反射进行泛化,或者像我喜欢的那样,可以编写一个生成器来为您编写代码。
var queryString = `INSERT INTO "quiz_answer_details" (
"quiz_answer_id","question_id","type","choices","content"
) VALUES ` // `
// 5 = the number of columns you want to insert per row
params := make([]interface{},len(ins)*5)
for i,v := range ins {
pos := i * 5
// aggregate all fields into a single slice
params[pos+0] = v.QuizAnswerID
params[pos+1] = v.QuestionID
params[pos+2] = v.Type
params[pos+3] = pq.Array(v.Choices)
params[pos+4] = v.Content
// construct the ($N,$N,...) lists for the VALUES clause
queryString += `($` + strconv.Itoa(pos+0) +
`,$` + strconv.Itoa(pos+1) +
`,$` + strconv.Itoa(pos+2) +
`,$` + strconv.Itoa(pos+3) +
`,$` + strconv.Itoa(pos+4) +
`),`
}
queryString = queryString[:len(queryString)-1] // drop the last comma
queryString += ` RETURNING *`
rows,err := db.QueryContext(ctx,queryString,params...)
if err != nil {
return err
}
defer rows.Close()
i := 0
for rows.Next() {
err := rows.Scan(
// NOTE: since you're using "RETURNING *" you need to
// provide fields for every column that will be returned,// and you need to make sure that the fields are in the
// same order in which their corresponding columns are
// declared in the table.
//
// NOTE: postgres,AFAIK,does NOT GUARANTEE that the returned
// rows will be in the same order in which they were inserted,// therefore the contents of the input slice may be in a
// different order after scanning is done.
&ins[i].QuizAnswerID,&ins[i].QuestionID,&ins[i].Type,pq.Array(&ins[i].Choices),&ins[i].Content,)
if err != nil {
return err
}
i += 1
}
return rows.Err()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。