doumi7861 2017-11-04 17:54
浏览 133
已采纳

如何从数组动态生成SQL查询列名称和值?

I have about 20 columns in one row and not all columns are required to be filled in when row created also i dont want to cardcode name of every column in SQL query and on http.post request on frontend. All values are from form. My code:

var colNames, values []string

for k, v := range formData {
    colNames = append(colNames, k)
    values = append(values, v)
}

Now i have 2 arrays: one with column names and second with values to be inserted. I want to do something like this:

db.Query("insert into views (?,?,?,?,?,?) values (?,?,?,?,?,?)", colNames..., values...)

or like this:

db.Query("insert into views " + colNames + " values" + values)

Any suggestions? Thanks!

  • 写回答

1条回答 默认 最新

  • dsafew1231 2017-11-04 18:59
    关注

    I assume your code examples are just pseudo code but I'll state the obvious just in case.

    db.Query("insert into views (?,?,?,?,?,?) values (?,?,?,?,?,?)", colNames..., values...)
    

    This is invalid Go since you can only "unpack" the last argument to a function, and also invalid MySQL since you cannot use placeholders (?) for column names.

    db.Query("insert into views " + colNames + " values" + values)
    

    This is also invalid Go since you cannot concatenate strings with slices.


    You could fromat the slices into strings that look like this:

    colNamesString := "(col1, col2, col3)"
    valuesString   := "(val1, val2, val3)"
    

    and now your second code example becomes valid Go and would compile but don't do this. If you do this your app becomes vulnerable to SQL injection and that's something you definitely don't want.


    Instead do something like this:

    // this can be a package level global and you'll need
    // one for each table. Keep in mind that Go maps that
    // are only read from are safe for concurrent use.
    var validColNames = map[string]bool{
         "col1": true,
         "col2": true,
         "col3": true,
         // ...
    }
    
    // ...
    
    var colNames, values []string
    var phs string // placeholders for values
    
    for k, v := range formData {
        // check that column is valid
        if !validColNames[k] {
            return ErrBadColName
        }
        colNames = append(colNames, k)
        values = append(values, v)
        phs += "?,"
    }
    
    if len(phs) > 0 {
        phs = phs[:len(phs)-1] // drop the last comma
    }
    phs = "(" + phs + ")"
    
    colNamesString := "(" + strings.Join(colNames, ",") + ")"
    query := "insert into views " + colNamesString + phs
    db.Query(query, values...)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 Matlab打开默认名称带有/的光谱数据
  • ¥50 easyExcel模板 动态单元格合并列
  • ¥15 res.rows如何取值使用
  • ¥15 在odoo17开发环境中,怎么实现库存管理系统,或独立模块设计与AGV小车对接?开发方面应如何设计和开发?请详细解释MES或WMS在与AGV小车对接时需完成的设计和开发
  • ¥15 CSP算法实现EEG特征提取,哪一步错了?
  • ¥15 游戏盾如何溯源服务器真实ip?需要30个字。后面的字是凑数的
  • ¥15 vue3前端取消收藏的不会引用collectId
  • ¥15 delphi7 HMAC_SHA256方式加密
  • ¥15 关于#qt#的问题:我想实现qcustomplot完成坐标轴
  • ¥15 下列c语言代码为何输出了多余的空格