Qu'est-ce que Go veut pour le deuxième paramètre de cette requête SQL ... Je tente d'utiliser la recherche IN
dans postgres
stmt, err := db.Prepare("SELECT * FROM awesome_table WHERE id= $1 AND other_field IN $2")
rows, err := stmt.Query(10, ???)
Ce que je veux vraiment:
SELECT * FROM awesome_table WHERE id=10 AND other_field IN (this, that);
Query demande juste varargs pour remplacer les params de votre sqlso, dans votre exemple,
rows, err := stmt.Query(10)
dire, ceci et celui de votre deuxième exemple étaient dynamiques, alors vous feriez
stmt, err := db.Prepare("SELECT * FROM awesome_table WHERE id=$1 AND other_field IN ($2, $3)")
rows, err := stmt.Query(10,"this","that")
Si vous avez des arguments variables pour la partie "IN", vous pouvez faire ( jouer )
package main
import "fmt"
import "strings"
func main() {
stuff := []interface{}{"this", "that", "otherthing"}
sql := "select * from foo where id=? and name in (?" + strings.Repeat(",?", len(stuff)-1) + ")"
fmt.Println("SQL:", sql)
args := []interface{}{10}
args = append(args, stuff...)
fakeExec(args...)
// This also works, but I think it's harder for folks to read
//fakeExec(append([]interface{}{10},stuff...)...)
}
func fakeExec(args ...interface{}) {
fmt.Println("Got:", args)
}
Il semble que vous utilisiez le pilote pq . pq
a récemment ajouté le support Array spécifique à Postgres via pq.Array (voir demande d'extraction 466 ). Vous pouvez obtenir ce que vous voulez via:
stmt, err := db.Prepare("SELECT * FROM awesome_table WHERE id= $1 AND other_field = ANY($2)")
rows, err := stmt.Query(10, pq.Array([]string{'this','that'})
Je pense que cela génère le SQL:
SELECT * FROM awesome_table WHERE id=10 AND other_field = ANY('{"this", "that"}');
Notez que ceci utilise des instructions préparées, les entrées doivent donc être désinfectées.
Si quelqu'un comme moi essayait d'utiliser un tableau avec une requête, voici une solution simple.
get https://github.com/jmoiron/sqlx
ids := []int{1, 2, 3}
q,args,err := sqlx.In("SELECT id,username FROM users WHERE id IN(?);", ids) //creates the query string and arguments
//you should check for errors of course
q = sqlx.Rebind(sqlx.DOLLAR,q) //only if postgres
rows, err := db.Query(q,args...) //use normal POSTGRES/ANY SQL driver important to include the '...' after the Slice(array)
Avec PostgreSQL, au moins, vous avez la possibilité de transmettre l’ensemble du tableau sous forme de chaîne, en utilisant un seul espace réservé:
db.Query("select 1 = any($1::integer[])", "{1,2,3}")
De cette façon, vous pouvez utiliser une seule chaîne de requête et toute la concaténation de chaîne est limitée au paramètre. Et si le paramètre est mal formé, vous ne recevez pas d'injection SQL; vous obtenez juste quelque chose comme: ERROR: syntaxe d'entrée invalide pour l'entier: "xyz"
https://groups.google.com/d/msg/golang-nuts/vHbg09g7s2I/RKU7XsO25SIJ
Plutôt piéton et à n'utiliser que si le serveur est généré. Où UserIDs est une tranche (liste) de chaînes:
sqlc := `select count(*) from test.Logins where UserID
in ("` + strings.Join(UserIDs,`","`) + `")`
errc := db.QueryRow(sqlc).Scan(&Logins)
Vous pouvez également utiliser cette conversion directe.
awesome_id_list := []int{3,5,8}
var str string
for _, value := range awesome_id_list {
str += strconv.Itoa(value) + ","
}
query := "SELECT * FROM awesome_table WHERE id IN (" + str[:len(str)-1] + ")"
ATTENTION
Cette méthode est vulnérable à l’injection SQL. Utilisez cette méthode uniquement si awesome_id_list
est généré par le serveur.