Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Golang ORDER BY-Problem mit MySql

Platzhalter ('?' ) können nur verwendet werden, um dynamische, maskierte Werte für Filterparameter einzufügen (z. B. im WHERE Teil), wo Datenwerte erscheinen sollen, nicht für SQL-Schlüsselwörter, Bezeichner usw. Sie können es nicht verwenden, um den ORDER BY dynamisch anzugeben ODER GRUPPE NACH Werte.

Sie können es trotzdem tun, zum Beispiel können Sie fmt.Sprintf() um den dynamischen Abfragetext wie folgt zusammenzustellen:

ordCol := "title"

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

Dinge, die Sie beachten sollten:

Dabei müssen Sie sich manuell gegen die SQL-Injection verteidigen, z. Wenn der Wert des Spaltennamens vom Benutzer stammt, können Sie keinen Wert akzeptieren und ihn einfach direkt in die Abfrage einfügen, sonst kann der Benutzer alle möglichen schlechten Dinge tun. Trivialerweise sollten Sie nur Buchstaben des englischen Alphabets + Ziffern + Unterstrich ('_') akzeptieren ).

Ohne zu versuchen, eine vollständige, allumfassende Prüf- oder Escape-Funktion bereitzustellen, können Sie diesen einfachen regulären Ausdruck verwenden, der nur englische Buchstaben, Ziffern und '_' akzeptiert :

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

Beispiele (probieren Sie es auf dem Go Playground aus ):

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