github.com/jackc/pgx/v5 v5.7.6 での検証
pgx.Conn
pgx.Connを使っている場合は、[]stringをそのまま使えるのであまり考える必要はない。
package main import ( "context" "fmt" "log" "github.com/jackc/pgx/v5" ) func main() { ctx := context.Background() conn, err := pgx.Connect(ctx, "postgres://postgres@localhost:5432/postgres") if err != nil { log.Fatal(err) } defer conn.Close(ctx) // CREATE TABLE users ( // id SERIAL PRIMARY KEY, // name VARCHAR(100), // email TEXT, // tags VARCHAR(50)[] // ); var name string var tags []string emails := []string{"sugawara@example.com", "hoge@example.com"} err = conn.QueryRow(ctx, "SELECT name, tags FROM users WHERE email = ANY($1)", emails).Scan(&name, &tags) if err != nil { log.Fatal(err) } fmt.Println(name, tags) //=> sugawara [foo bar zoo] }
stdlib
プレースホルダーにstring配列を渡す
プレースホルダーには[]stringをそのまま渡せる。
package main import ( "database/sql" "fmt" "log" _ "github.com/jackc/pgx/v5/stdlib" ) func main() { db, err := sql.Open("pgx", "postgres://postgres@localhost:5432/postgres") if err != nil { log.Fatal(err) } defer db.Close() // CREATE TABLE users ( // id SERIAL PRIMARY KEY, // name VARCHAR(100), // email TEXT, // tags VARCHAR(50)[] // ); var name string emails := []string{"sugawara@example.com", "hoge@example.com"} err = db.QueryRow("SELECT name FROM users WHERE email = ANY($1)", emails).Scan(&name) if err != nil { log.Fatal(err) } fmt.Println(name) //=> sugawara }
結果のstring配列を受け取る
string配列を受け取る場合はpgtype.NewMapを使う必要がある。
package main import ( "database/sql" "fmt" "log" "github.com/jackc/pgx/v5/pgtype" _ "github.com/jackc/pgx/v5/stdlib" // "github.com/lib/pq" ) func main() { db, err := sql.Open("pgx", "postgres://postgres@localhost:5432/postgres") if err != nil { log.Fatal(err) } defer db.Close() // CREATE TABLE users ( // id SERIAL PRIMARY KEY, // name VARCHAR(100), // email TEXT, // tags VARCHAR(50)[] // ); var tags []string err = db.QueryRow("SELECT tags FROM users WHERE name = $1", "sugawara").Scan(pgtype.NewMap().SQLScanner(&tags)) // あるいは pq.Arrayを使う https://pkg.go.dev/github.com/lib/pq#Array //err = db.QueryRow("SELECT tags FROM users WHERE name = $1", "sugawara").Scan(pq.Array(&tags)) if err != nil { log.Fatal(err) } fmt.Println(tags) //=> [foo bar zoo] }
以下のIssueではpgtype.FlatArrayを使っているが不要なようだった。
https://github.com/jackc/pgx/blob/61d3c965ad442cc14d6b0e39e0ab3821f3684c03/stdlib/sql.go#L58-L65
// # PostgreSQL Specific Data Types // // The pgtype package provides support for PostgreSQL specific types. *pgtype.Map.SQLScanner is an adapter that makes // these types usable as a sql.Scanner. // // m := pgtype.NewMap() // var a []int64 // err := db.QueryRow("select '{1,2,3}'::bigint[]").Scan(m.SQLScanner(&a))