用slice执行sql prepared语句

时间:2014-06-22 17:10:43

标签: mysql sql go

我写了一个函数(当然是Go),它通过this库将map[string]interface{}插入mysql。

以下代码说明:

  1. 这些函数会收到名为 table string和名为 data map[string]interface{}
  2. 我将data分隔为键(名为 columns 的变量)和值(名为 values 的变量)。
  3. 我从名为 column_text columns 变量生成,如下所示:first_name, last_name, birth_day, date_added
  4. 我从名为 variable_text values 变量生成,如下所示:?, ?, ?, ?
  5. 我打开mysql连接:db, err := sql.Open("mysql", "user:pass@/database")
  6. 我创建了准备好的声明:stmt, err := db.Prepare("INSERT INTO " + table + " ( " + columns_text + " ) VALUES ( " + values_text + " )")
  7. 我执行prepare语句。但我有一个问题。列数和值的数量一直在变化,stmt.Exec()命令无法接收像这样的切片(数组):stmt.Exec(values),只有像这样的值:stmt.Exec(values[0], values[1], values[2]...)
  8. 问题:

    我来自PHP,其中PDO :: Statement在执行时可以接收数组。 如何用slice(Array)执行语句? (如果我可以使用不同的库,请写出库的名称以及如何使用它,谢谢!)

    代码:

    func insertToDB(table string, data map[string]interface{}) {
    columns := make([]interface{}, 0, len(data))
    values := make([]interface{}, 0, len(data))
    
    for  key, _ := range data {
       columns = append(columns, key)
       values = append(values, data[key])
    }
    
    columns_text := ""
    i := 0
    of := len(data)
    
    for i < of {
        column := columns[i].(string)
    
        if i == 0 {
            columns_text = column
        } else {
            columns_text = columns_text + ", " + column
        }
    
        i++
    }
    
    fmt.Println(columns_text + " = " + table)
    
    values_text := ""
    
    i = 0
    
    for i < of {
    
        if i == 0 {
            values_text = "?"
        } else {
            values_text = values_text + ", ?"
        }
    
        i++
    }
    
    fmt.Println(values_text)
    fmt.Println(values)
    fmt.Println(data)
    
    db, err := sql.Open("mysql", "root:root@/bacafe")
    if err != nil {
        return -1, err
    }
    defer db.Close()
    
    stmtIns, err := db.Prepare("INSERT INTO " + table + " ( " + columns_text + " ) VALUES ( " +  values_text + " )")
    if err != nil {
        return -1, err
    }
    defer stmtIns.Close() // Close the statement when we leave main() / the program terminates
    
    result, err := stmtIns.Exec(values...)
    if err != nil {
        return -1, err
    } else {
        insertedID, err := result.LastInsertId()
        if err != nil {
            return -1, err
        } else {
            return int(insertedID), nil
        }
    }
    }
    

    编辑:我已经编辑了上面的功能,现在效果很好。

    谢谢!

1 个答案:

答案 0 :(得分:6)

您走在正确的轨道上,Stmt.Exec需要args ...interface{},所以对于您的具体示例,您需要更改两件事:

......
values := make([]interface{}, 0, len(data))
......
//adding ... expands the values, think of it like func.apply(this, array-of-values) in 
// javascript, in a way.
_, err = stmtIns.Exec(values...)