如何使用参数化查询按名称搜索列?

时间:2015-07-08 21:57:56

标签: mysql sql go sql-injection

我的用户应该可以通过在输入框中输入搜索字词并选择他们想要从下拉框中搜索的列来搜索数据库。

但是,我找不到在golang中参数化查询的方法,以便将列名识别为列名而不是值。让我举个例子:

rows, err := db.Query("SELECT * FROM mytable WHERE ? = ?", col, searchStr)

我启用了MySQL日志记录,这是最终的查询:

   41 Execute   SELECT *
    FROM mytable 
    WHERE 'Username' = 'Foo'

显然Username不应该有单引号。

如何参数化此查询?我是否必须编写应用程序逻辑来检查每个查询是否有正确的列名,并使用字符串操作将列名添加到查询中(可能使用一些占位符字符来查找和替换)?

2 个答案:

答案 0 :(得分:4)

这是为了帮助您避免糟糕的args(防止SQL注入之类的事情),但不是为了替换除值以外的任何东西。您希望它插入表名。不幸的是,代码知道db.Query(fmt.Sprintf("SELECT * FROM mytable WHERE %s = ?", col), searchStr) 的类型(字符串)并引用它,因为在SQL中它是nvarchar,这就是它们的文字编写方式,用单引号括起来。可能看起来有点像黑客,但你需要这个;

Query

在将表名传递给public function login($attempt) { $CI = & get_instance(); $CI->load->model("users"); // Store password entry $password = $attempt["password"]; // Get user from database $user = $CI->users->get(array("screen_name" => $attempt["screen_name"])); if (!array_key_exists("password", $user)) { return null; } // Validate password $valid = crypt($password, $user["password"]) == $user["password"]; if ($valid) { // Remove password - user data will be stored in session unset($user["password"]); // If no photo uploaded, set default if (!isset($user["photo"]) || $user["photo"] == null) { $user["photo"] = "http://oururl/ourroute/assets/images/DefaultAvatar.png"; } else { //$user["photo"] = "files/images/" . $user["photo"]; } return $user; } else { return false; } } 之前将其放入查询字符串中,这样它就不会被视为参数(即where子句中使用的值)。

答案 1 :(得分:2)

你应该看看这个包。 https://github.com/gocraft/dbr

这对你想做的事情很有帮助。

import "github.com/gocraft/dbr"

// Simple data model
type Suggestion struct {
    Id        int64
    Title     string
    CreatedAt dbr.NullTime
}

var connection *dbr.Connection

func main() {

    db, _ := sql.Open("mysql","root@unix(/Applications/MAMP/tmp/mysql/mysql.sock)/dbname")
    connection = dbr.NewConnection(db, nil)
    dbrSess := connection.NewSession(nil)

    // Get a record
    var suggestion Suggestion
    err := dbrSess.Select("id, title").From("suggestions").
        Where("id = ?", 13).
        LoadStruct(&suggestion)

    if err != nil {
             fmt.Println(err.Error())
    } else {
             fmt.Println("Title:", suggestion.Title)
    }
}