【问题标题】:GoLang Dynamic SQL Query in App EngineApp Engine 中的 GoLang 动态 SQL 查询
【发布时间】:2018-02-22 23:28:09
【问题描述】:

我想在 GoLang 中创建动态 sql,但我似乎找不到正确的方法。

基本上,我只想做:

query := "SELECT id, email, something FROM User"

var paramValues []string
filterString := ""

if userParams.Name != "" {
    paramString += " WHERE id = ?"
    paramValues = append(paramValues, userParams.Name)
}

if userParams.UserID != "" {
    if len(paramString) > 0 {
        paramString += " AND"
    } else {
        paramString += " WHERE"
    }

    paramString += " email = ?"
    paramValues = append(paramValues, userParams.UserID)
}
stmtOut, err := db.Prepare(query + paramString)

err = stmtOut.QueryRow(paramValues).Scan(&id, &email, &something)

building a dynamic query in mysql and golang相关

我一直无法找到一种不允许 sql 注入的可靠方法。我上述解决方案的问题是 QueryRow() 没有将 []string 作为参数。

我想防止 SQL 注入,所以 fmt.Sprintf 并不能真正解决问题。

这样我可以允许使用 ID 或电子邮件搜索用户,并且我还将将此逻辑用于具有更多可搜索字段的不同对象。

我正在使用 go-sql-driver/mysql

【问题讨论】:

    标签: mysql sql google-app-engine go dynamic


    【解决方案1】:

    这是我可以在本地机器上运行的东西(go1.8 linux/amd64 和当前的 GO MySQL 驱动程序 1.3)。

    演示了几种方法。

    package main
    
    import (
        "database/sql"
        "log"
    
        _ "github.com/go-sql-driver/mysql"
    
        "fmt"
    )
    
    // var db *sql.DB
    // var err error
    
    /*
    Database Name/Schema : Test123
    Table Name: test
    Table Columns and types:
    number INT (PRIMARY KEY)
    cube INT
    */
    
    func main() {
        //Username root, password root
        db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/Test123?charset=utf8")
    
        if err != nil {
            fmt.Println(err) // needs proper handling as per app requirement
            return
        }
        defer db.Close()
    
        err = db.Ping()
        if err != nil {
            fmt.Println(err) // needs proper handling as per app requirement
            return
        }
    
        //Prepared statement for inserting data
        stmtIns, err := db.Prepare("INSERT INTO test VALUES( ?, ? )") // ? = placeholders
        if err != nil {
            panic(err.Error()) // needs proper handling as per app requirement
        }
        defer stmtIns.Close()
    
        //Insert cubes of 1- 10 numbers
    
        for i := 1; i < 10; i++ {
            _, err = stmtIns.Exec(i, (i * i * i)) // Insert tuples (i, i^3)
            if err != nil {
                panic(err.Error()) // proper error handling instead of panic in your app
            }
        }
    
        num := 3
    
        // Select statement
    
        dataEntity := "cube"
        condition := "WHERE number=? AND cube > ?"
        finalStatement := "SELECT " + dataEntity + " FROM test " + condition
        cubeLowerLimit := 10
    
        var myCube int
        err = db.QueryRow(finalStatement, num, cubeLowerLimit).Scan(&myCube)
        switch {
        case err == sql.ErrNoRows:
            log.Printf("No row with this number %d", num)
        case err != nil:
            log.Fatal(err)
        default:
            fmt.Printf("Cube for %d is %d\n", num, myCube)
        }
    
        var cubenum int
    
        // //Prepared statement for reading data
        stmtRead, err := db.Prepare(finalStatement)
        if err != nil {
            panic(err.Error()) // needs proper err handling
        }
        defer stmtRead.Close()
    
        // Query for cube of 5
        num = 5
        err = stmtRead.QueryRow(num, cubeLowerLimit).Scan(&cubenum)
        switch {
        case err == sql.ErrNoRows:
            log.Printf("No row with this number %d", num)
        case err != nil:
            log.Fatal(err)
        default:
            fmt.Printf("Cube number for %d is %d\n", num, cubenum)
        }
    
    }
    

    如果您随后运行它,您需要删除数据库中的行,以便插入不会造成恐慌(或者更改插入行代码,使其不会恐慌)。我还没有在 Google App Engine 上尝试过。希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2019-08-17
      • 2011-07-05
      • 1970-01-01
      • 1970-01-01
      • 2021-07-31
      • 2017-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多