问题
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 :
aID
does contain all those numbers as string andtable has all the rows available with provided above
id
.table
is from whereid
is fetched and appended toaID
and another records withid
stored inaID
are fetched within
statement 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