问题
I am trying to run query like below , but only first id value returns :-
select * from `table` where table`.`id` in ('1', '2', '3', '4', '5', '6', '7', '9', '11', '13', '14', '15', '17') and `table`.`deleted_at` is null
I have done following :-
var aID = make([]string, 0)
var in india // india is struct
for rows.Next() {
cook := rows.Scan(&in.ID)
aID = append(aID, strconv.Itoa(in.ID))
}
asID = strings.Join(aID, ",")
anotherRow,err := db.Query("SELECT * from table2 where id in (?)", asID)
if err != nil { fmt.Printf("Error: ", err) }
// ... Other line follows up with "for anotherRow.Next() and fetching"
While fetching data, it only returns value of "1" and ignores all other ID passed on with him, which are '2', '3', '4', '5', '6', '7', '9', '11', '13', '14', '15', '17'.
How can i pass it correctly ?
I am using go-sql-driver/mysql.
FAQ :
aIDdoes contain all those numbers as string andtable has all the rows available with provided above
id.tableis from whereidis fetched and appended toaIDand another records withidstored inaIDare fetched withinstatement fromtable2.
Thanks
回答1:
You can do something like this:
args := make([]interface{}, len(asID))
for i, id := range asID {
args[i] = id
}
stmt := `SELECT * from table2 where id in (?` + strings.Repeat(",?", len(args)-1) + `)`
anotherRow, err := db.Query(stmt, args...)
Just note you will want to put in a guard if asID can ever have len == 0.
If you have any other arguments to pass in, you'll have to add them to the args slice.
Also to note, you should explicitly name the columns you want so you can guarantee you are scanning in the correct columns to the correct fields.
回答2:
Try
q,args,err := sqlx.In("SELECT * FROM table2 WHERE id IN(?);", asID) //creates the query string and arguments
rows, err := db.Query(q,args...)
You could also use the Masterminds/squirrel package:
import sq "github.com/Masterminds/squirrel"
...
users := sq.Select("*").From("table2")
active := users.Where(sq.Eq{"id":[]string{"1","2","3"}})
sql, args, err := active.ToSql()
Which will do the in clause automatically when using sq.Eq struct with a slice.
回答3:
example:
idAry := []string{"1", "2", "3"}
ids := strings.Join(idAry, "','")
sqlRaw := fmt.Sprintf(`SELECT * FROM table WHERE id IN ('%s')`, ids)
rows, err := db.Query(sqlRaw)
It works fine
回答4:
The most elegant solution for queries to make array/slice work directly with sql queries. This also sql injection proof as you are not using string concatenation rather using sql prepared statement
idAry := []string{"1", "2", "3"}
q := "SELECT * FROM table WHERE id = any($1);"
rows, err := db.Exec(q, pq.Array(authors))
回答5:
Since you're dealing with ids from your own database and if you are certain there is no way someone could inject malicious "ids" into that code, don't use the placeholder ? and just use the fmt package.
fmt.Sprintf("SELECT * from table2 where id in (%s)", asID)
this will result in SELECT * from table2 where id in (1,2,3,4...) as opposed to SELECT * from table2 where id in ('1,2,3,4...')
来源:https://stackoverflow.com/questions/45351644/golang-slice-in-mysql-query-with-where-in-clause