将数组传递给 go-pg 查询

pass array to go-pg query

我正在使用 Go-pg,当我使用以下方式执行 sql 查询时:

db.Query(&result, sqlQuery, params)

其中 params 是如下结构:

type MyParams struct {
    Codes []int
}

并且 sqlQuery

SELECT id FROM bar WHERE code_id IN (?codes)

在实际的 SQL 查询中,我得到这样的查询:

SELECT id FROM bar WHERE code_id IN ('[7,45]')

是否可以正确传递 int 数组占位符以进行查询:

SELECT id FROM bar WHERE code_id IN (7,45)

一种方法是创建一个带有分隔符的字符串,然后将其传递给 db.query 以获取结果。

package main

import (
    "fmt"
    "strconv"
    "strings"
)

func main() {
    a := []int{7,45,32}
    str := ConvertToString(a, ",")
    query := `Select * from table1 where ID IN(`+ str +`)`
    fmt.Println(query)
}

func ConvertToString(a []int, delim string) string{
    var b string
    for _, v := range a{
        b += strconv.Itoa(v)
        b += ","
    }
    return strings.Trim(b,",")
}

Playground 上的工作代码。

已编辑:-

您可以根据需要使用 Golang sqlx 包。

database/sql package does not inspect your query and it passes your arguments directly to the driver, it makes dealing with queries with IN clauses difficult:

SELECT * FROM users WHERE level IN (?);

When this gets prepared as a statement on the backend, the bindvar ? will only correspond to a single argument, but what is often desired is for that to be a variable number of arguments depending on the length of some slice, eg:

var levels = []int{4, 6, 7}
rows, err := db.Query("SELECT * FROM users WHERE level IN (?);", levels)

您可以做几件事:

  1. 继续使用 in (...) 并使用 pg.In
  2. 在 Go 中使用 = any(array) in your SQL instead of in (list) and pg.Array 将适当的数组发送到 PostgreSQL。

第一个看起来像:

db.Query(&result, `SELECT id FROM bar WHERE code_id IN (?)`, pg.In(params.Codes))

第二个看起来像:

db.Query(&result, `SELECT id FROM bar WHERE code_id = ANY (?)`, pg.Array(params.Codes))

您可以改用 go-pg ORM 以获得相同的结果:

ids := []int{1, 2, 3}
err := db.Model((*Book)(nil)).
    Where("id in (?)", pg.In(ids)).
    Select()

// SELECT * FROM books WHERE id IN (1, 2, 3)