1
1

More than 3 years have passed since last update.

【Go】sqlxのNamedStmtでIN句の条件数を動的に指定する

Last updated at Posted at 2020-11-12

sqlxでIN句を含むクエリをNamedStmtで扱う方法のサンプルコードです。
EXISTS句にも応用可能です。

サンプルコード

main.go
func main() {
    userIds := []int{1, 2, 3, 4, 5}
    age := 20
    select(ids, createdAt)
}
select.go
var db *sqlx.DB

func select(userIds []int, age int) ([]User, error) {

    // SQLの雛形
    originQuery := `SELECT * FROM USER WHERE USER_ID IN (:USER_ID) AND AGE > :AGE`

    // バインドする値
    arg := map[string]interface{}{
        "USER_ID":  userIds,
        "AGE": age,
    }

    // NamedStmtでIN句を使える形式にする
    query, params := formatQuery(&originQuery, &arg)

    // Select文を実行
    namedStmt, err := db.PrepareNamedContext(context.Background(), *query)
    if err != nil {
        return nil, err
    }
    defer namedStmt.Close()

    var users []User
    if err := namedStmt.SelectContext(context.Background(), &sqlxSamples, *params); err != nil {
        return nil, err
    }

    return users, nil
}
format.go
func formatQuery(q *string, a *map[string]interface{}) (*string, *map[string]interface{}) {

    query, args, _ := sqlx.Named(*q, *a)
    fmt.Println(query) // SELECT * FROM USER WHERE USER_ID IN (?) AND AGE > ?
    fmt.Println(args)  // [[1 2 3 4 5] 20]

    query, args, _ = sqlx.In(query, args...)
    fmt.Println(query) // SELECT * FROM USER WHERE USER_ID IN (?, ?, ?, ?, ?) AND AGE > ?
    fmt.Println(args)  // [1 2 3 4 5 20]

    query = sqlx.Rebind(sqlx.NAMED, query)
    params := map[string]interface{}{}
    for i, arg := range args {
        key := fmt.Sprintf("arg%d", i+1)
        params[key] = arg
    }
    fmt.Println(query)  // SELECT * FROM USER WHERE USER_ID IN (:arg1, :arg2, :arg3, :arg4, :arg5) AND AGE > :arg6
    fmt.Println(params) // map[arg1:1 arg2:2 arg3:3 arg4:4 arg5:5 arg6:20]

    return &query, &params
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1