Передать массив в запрос 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 ответа
Есть пара вещей, которые вы можете сделать:
- Продолжайте использовать
in (...)
и использоватьpg.In
, - использование
= 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)