1

插入一条记录并获得如下结果很容易:

    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, question_id, type, choices, content) VALUES ($1, $2, $3, $4, $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, d.QuizAnswerID, d.QuestionID, d.Type, 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

提前致谢

4

1 回答 1

0

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()
于 2021-07-25T05:43:46.983 回答