Cross-database prepared statement binding (like and where in) in Golang

前端 未结 3 600
南笙
南笙 2021-01-19 12:43

After reading many tutorials, I found that there are many ways to bind arguments on prepared statement in Go, some of them

SELECT * FROM bla WHERE x = ?col1          


        
3条回答
  •  -上瘾入骨i
    2021-01-19 13:32

    I had this same question, and after reading the answers started to look for other solution on how to bind arguments for the IN statement.

    Here is an example of what I did, not the most elegant solution, but works for me.

    What I did was to create a select query with the parameters statically set on the query, and not using the bind feature at all.

    It could be a good idea to sanitize the string that comes from the Marshal command, to be sure and safe, but I don't need it now.

    package main
    
    import (
        "database/sql"
        "encoding/json"
        "fmt"
        "log"
    
        _ "github.com/go-sql-driver/mysql"
    )
    
    type Result struct {
        Identifier string
        Enabled    bool
    }
    
    func main() {
    
        // Open connection
        db, err := sql.Open("mysql", "username:password@tcp(server-host)/my-database")
        if err != nil {
            panic(err.Error()) // proper error handling instead of panic in your app
        }
        defer db.Close()
    
        // this is an example of a variable list of IDs
        idList := []string{"ID1", "ID2", "ID3", "ID4", "ID5", "IDx"}
    
        // convert the list to a JSON string
        formatted, _ := json.Marshal(idList)
    
        // a JSON array starts and ends with '[]' respectivelly, so we replace them with '()'
        formatted[0] = '('
        formatted[len(formatted)-1] = ')'
    
        // create a static select query
        query := fmt.Sprintf("SELECT identifier, is_enabled FROM some_table WHERE identifier in %s", string(formatted))
    
        // prepare que query
        rows, err := db.Query(query)
        if err != nil {
            panic(err.Error()) // proper error handling instead of panic in your app
        }
        defer rows.Close()
    
        var result []Result
        // fetch rows
        for rows.Next() {
            var r0 Result
            if err := rows.Scan(&r0.Identifier, &r0.Enabled); err != nil {
                log.Fatal(err)
            }
            // append the row to the result
            result = append(result, r0)
        }
        if err := rows.Err(); err != nil {
            log.Fatal(err)
        }
    
        fmt.Printf("result = %v\n", result)
    }
    

提交回复
热议问题