与MySql的Golang ORDER BY问题

Aar*_*nny 8 mysql database go

我似乎无法使用db.Select()动态ORDER BY.我用Google搜索没有运气......

作品

rows, err := db.Query("SELECT * FROM Apps ORDER BY title DESC")

什么都不行

rows, err := db.Query("SELECT * FROM Apps ORDER BY ? DESC", "title")

我没有收到任何错误,查询根本无法订购.

icz*_*cza 8

占位符('?')只能用于为过滤器参数(例如在WHERE部件中)插入动态的转义值,其中应显示数据值,而不是SQL关键字,标识符等.您不能使用它来动态指定ORDER BYOR GROUP BY值.

你仍然可以这样做,例如你可以fmt.Sprintf()用来组装动态查询文本,如下所示:

ordCol := "title"

qtext := fmt.Sprintf("SELECT * FROM Apps ORDER BY %s DESC", ordCol)
rows, err := db.Query(qtext)
Run Code Online (Sandbox Code Playgroud)

要记住的事情:

这样做你将不得不手动防御vs SQL注入,例如,如果列名的值来自用户,你不能接受任何值,只需将其直接插入查询,否则用户将能够做各种不好的事情的东西.平凡的,你应该只接受英文字母+数字+下划线('_')的字母.

如果不尝试提供完整的,全面的检查器或转义函数,您可以使用这个简单的正则表达式,它只接受英文字母,数字和'_':

valid := regexp.MustCompile("^[A-Za-z0-9_]+$")
if !valid.MatchString(ordCol) {
    // invalid column name, do not proceed in order to prevent SQL injection
}
Run Code Online (Sandbox Code Playgroud)

示例(在Go Playground上试试):

fmt.Println(valid.MatchString("title"))         // true
fmt.Println(valid.MatchString("another_col_2")) // true
fmt.Println(valid.MatchString("it's a trap!"))  // false
fmt.Println(valid.MatchString("(trap)"))        // false
fmt.Println(valid.MatchString("also*trap"))     // false
Run Code Online (Sandbox Code Playgroud)