dongqiao8417 2017-10-21 03:16
浏览 174
已采纳

对MySQL数据库进行动态SQL查询

I've never used golang with mysql before, so I'm reading about these for the first time. I'd like to do something like this:

if userId && gender && age
db.QueryRow("SELECT name FROM users WHERE userId=? AND gender=? AND age=?", userId,gender,age)
else if gender && age
db.QueryRow("SELECT name FROM users WHERE gender=? AND age=?", gender, age)
else if userId && gender
db.QueryRow("SELECT name FROM users WHERE userId=? AND gender=?", userId,gender)
else if userId && age
db.QueryRow("SELECT name FROM users WHERE userId=? AND age=?", userId, age)
else if gender
db.QueryRow("SELECT name FROM users WHERE gender=?", gender)
else if userId
db.QueryRow("SELECT name FROM users WHERE userId=?", userId)
else if age
db.QueryRow("SELECT name FROM users WHERE age=?", age)

This is far too much typing, especially if I have a dozen more variables I'd like to add to the WHERE condition.

If this were PHP, I'd do something like this:

$sql = "SELECT name FROM users ";
$where = array();
foreach(explode(",","userId,gender,age,name,height,weight,ethnicity" as $field)
{
    if(isset($arrayOfValues[$field]))
    {
        $where[count($where)] = $field." = ?".$field
        $db->bind("?".$field,$arrayOfValues[$field]);
    }
}

if(count($where)>0)
$sql = $sql . " WHERE ".implode(" AND ",$where);
$db->query($sql);

By using a foreach loop, I can dynamically generate queries and dynamically bind as many variables as needed.

Is something like this an option with golang and mysql? Or are there alternatives to not typing out every single variable combination for a query?

  • 写回答

1条回答 默认 最新

  • doukui9491 2017-10-21 03:30
    关注

    If you have a map with the field names and values like this:

    m := map[string]interface{}{"UserID": 1234, "Age": 18}
    

    then you can build the query like this:

    var values []interface{}
    var where []string
    for _, k := range []string{"userId","gender","age","name","height","weight","ethnicity"}
    if v, ok := m[k]; ok {
        values = append(values, v)
        where = append(where, fmt.Sprintf("%s = ?", k))
    }
    r, err := db.QueryRow("SELECT name FROM users WHERE " + strings.Join(where, " AND "), values...)
    

    This is not susceptible to SQL injection because placeholders are used for parts of the query outside the application's direct control.

    If the map keys are known to be allowed field names, then use this:

    var values []interface{}
    var where []string
    for k, v := range m {
        values = append(values, v)
        where = append(where, fmt.Sprintf("%s = ?", k))
    }
    r, err := db.QueryRow("SELECT name FROM users WHERE " + strings.Join(where, " AND "), values...)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容