はじめに
Go + sqlxでスライスを使ってクエリに複数の変数を渡す方法がよくわからなかったので、しらべて試した。
環境
これで作った環境を使ってる。
Dockerを使ってPostgreSQL+Goの開発環境を作ってみた - Qiita
コード
シンプルな方法
スライスをそのままわたす。
package main
import (
"fmt"
"log"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
)
// Employee は構造体です
type Employee struct {
id string
number string
}
func main() {
db, err := sqlx.Connect("postgres", "host=db port=5432 user=root sslmode=disable")
if err != nil {
log.Fatalln(err)
}
var nums = []int{4445, 5432}
query, args, err := sqlx.In("SELECT * FROM employee WHERE emp_number IN (?);", nums)
query = db.Rebind(query)
rows, err := db.Query(query, args...)
if err != nil {
fmt.Println(err)
}
var es []Employee
for rows.Next() {
var e Employee
rows.Scan(&e.id, &e.number)
es = append(es, e)
}
fmt.Println(es)
}
mapを使った方法
こっちだと、複数の変数(numsとidsとか)を渡せる。
ゴニョゴニョしてスライスを展開してる。
package main
import (
"fmt"
"log"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
)
// Employee は構造体です
type Employee struct {
id string
number string
}
func main() {
db, err := sqlx.Connect("postgres", "host=db port=5432 user=root sslmode=disable")
if err != nil {
log.Fatalln(err)
}
arg := map[string]interface{}{
"nums": []int{4445, 5432},
}
query, args, err := sqlx.Named(`SELECT * FROM employee WHERE emp_number IN (:nums);`, arg)
fmt.Println(query)
query, args, err = sqlx.In(query, args...)
fmt.Println(query)
query = db.Rebind(query)
rows, err := db.Query(query, args...)
if err != nil {
fmt.Println(err)
}
var es []Employee
for rows.Next() {
var e Employee
rows.Scan(&e.id, &e.number)
es = append(es, e)
}
fmt.Println(es)
}
おわりに
sqlx使ったけど、sqlパッケージでもできたりすんのかな?よくわからん。
構造体で渡す方法もあるけど、そっちはsliceを入れるやりかた見つからなかった。できるんかな?よくわからん。
参考
jmoiron/sqlx: general purpose extensions to golang's database/sql
Illustrated Guide to SQLX
Named parameters don't work with IN statement · Issue #485 · jmoiron/sqlx