Передать массив в запрос go-pg

Я использую 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]')

Можно ли правильно передать заполнитель массива in t для запроса:

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

3 ответа

Есть пара вещей, которые вы можете сделать:

  1. Продолжайте использовать in (...) и использовать pg.In,
  2. использование = any(array) в вашем SQL вместо in (list) а также pg.Array в Go, чтобы отправить правильный массив в 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))

Вместо этого вы можете использовать ORM go-pg для тех же результатов:

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)

Вы можете попробовать сделать что-то вроде этого:

// Slice with your integer IDs as strings.
ids := []string{}

// Convert integer ID to string ID.
for _, i := range []int{7, 45} {
    ids = append(ids, strconv.Itoa(i))
}

Теперь вы можете использовать Join func, и окончательный запрос будет выглядеть довольно просто, например так:

in := strings.Join(ids, ",")
query := "SELECT id FROM bar WHERE code_id IN (" + in + ")"

Можно создать строку с разделителем, необходимым для создания строки, а затем передать ее 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,",")
}

Рабочий код на детской площадке.

Отредактировано:-

Вы можете использовать пакет Golang sqlx по вашему требованию.

database/sql Пакет не проверяет ваш запрос и передает ваши аргументы непосредственно драйверу, что затрудняет работу с запросами с предложениями IN:

SELECT * FROM users WHERE level IN (?);

Когда это будет подготовлено как утверждение на бэкэнде, bindvar? будет соответствовать только одному аргументу, но часто требуется, чтобы это было переменное число аргументов в зависимости от длины некоторого фрагмента, например:

var levels = []int{4, 6, 7}
rows, err := db.Query("SELECT * FROM users WHERE level IN (?);", levels)
Другие вопросы по тегам