Trevor V
Trevor V

Reputation: 2141

Trying to query contains search in golang with Prepare

I have a prepare and a query function in go and when I place the ? in the search it works fine. When I try and do a contains search with the % I get sql: statement expects 0 inputs; got 1

How can I do this type of query without having the variables directly in the SQL? I want to prevent SQL injection . Thank You for your help.

I am using go version go1.8.1 darwin/amd64 and using MySQL

My Go Code:

stmt, err := dBusers.Prepare("SELECT id, name, email, username FROM users WHERE name LIKE '%?%';")
    if err != nil {
        logging.LogError("Could Not Query All Users: "+err.Error())
        return nil, errors.New("Could Not Query Users")
    }
    rows, err := stmt.Query(name)

Upvotes: 2

Views: 1792

Answers (2)

Cetin Basoz
Cetin Basoz

Reputation: 23837

You could either make the whole %searchValue% a parameter value itself, or use string concatenation for it inside the query itself.

Approach 1 (recommended):

stmt, err := dBusers.Prepare("SELECT id, name, email, username FROM users WHERE name LIKE ?;")
    if err != nil {
        logging.LogError("Could Not Query All Users: "+err.Error())
        return nil, errors.New("Could Not Query Users")
    }
    rows, err := stmt.Query("%" + name + "%")

Approach 2:

stmt, err := dBusers.Prepare("SELECT id, name, email, username FROM users WHERE name LIKE '%' + ? + '%';")
    if err != nil {
        logging.LogError("Could Not Query All Users: "+err.Error())
        return nil, errors.New("Could Not Query Users")
    }
    rows, err := stmt.Query(name) 

I would recommend the first approach because it wouldn't force you to always use a "contains' search. You could selectively use the same statement to do exact (just name), begins with (name+"%"), ends with ("%"+name) or contains ("%"+name+"%") searches.

PS: Thinking about it, the second approach might lead to injection, not sure, need to think about it more.

Upvotes: 0

Kaedys
Kaedys

Reputation: 10158

Reposting my comment as an answer so this question actually has one:

This answer suggests making your parameter argument (in this case, name) include the wildcards instead of the query. So stmt.Query("%" + name + "%"). This still prevents injection, because it's still being sent as a parameter instead of inline with the query.

Upvotes: 3

Related Questions