Коротко — самый простой, безопасный и понятный путь — подставлять пары как список VALUES и передавать сами значения как параметры. Примерно так:
- Собираете слайс аргументов []interface{}.
- Динамически генерируете "( $1,$2 ),( $3,$4 ),..." для VALUES.
- Выполняете запрос через sqlx (или pgx), передавая args...
Пример для sqlx + pgx (через pgx stdlib) — поиск по множеству пар целых значений:
```go
import (
"fmt"
"strings"
"github.com/jackc/pgx/v5/stdlib" // регистрирует драйвер "pgx"
"github.com/jmoiron/sqlx"
)
type Row struct {
Col1 int `db:"col1"`
Col2 int `db:"col2"`
// остальные поля...
}
func selectByPairs(db *sqlx.DB, pairs [][2]int) ([]Row, error) {
if len(pairs) == 0 {
return nil, nil // или вернуть пустой слайс / особую логику
}
args := make([]interface{}, 0, len(pairs)*2)
vals := make([]string, 0, len(pairs))
for i, p := range pairs {
// placeholders: $1,$2 $3,$4 ...
idx := i*2 + 1
vals = append(vals, fmt.Sprintf("($%d,$%d)", idx, idx+1))
args = append(args, p[0], p[1])
}
q := "SELECT * FROM my_table WHERE (col1, col2) IN (VALUES " + strings.Join(vals, ",") + ")"
var out []Row
if err := db.Select(&out, q, args...); err != nil {
return nil, err
}
return out, nil
}
```
Пояснения и замечания:
- Такой подход безопасен: все значения идут через параметры, SQL-инъекции исключены.
- Этот синтаксис (WHERE (a,b) IN (VALUES (...),(...))) полностью поддерживается PostgreSQL 11.
- Если нужно сохранить порядок результатов, соответствующий порядку входных пар, можно добавлять индекс в VALUES и JOIN:
q := "SELECT t.* FROM my_table t JOIN (VALUES ($1,$2,0), ($3,$4,1), ...) AS v(col1,col2,ord) USING (col1,col2) ORDER BY v.ord"
- Обработка пустого списка — отдельный случай: лучше заранее вернуть пустой результат или добавить условие LIKE "WHERE false".
- Если вы используете pgx напрямую (pgx.Conn / pgxpool), синтаксис $1,$2 остаётся таким же — подход аналогичен.
- Не используйте конкатенацию реальных значений в SQL строку — только placeholders.
Это простой, понятный и широко используемый способ без "магии" и без изменения версии PostgreSQL.