Pre-compilazione della query SQL (prevenzione dell'iniezione SQL)
Se stai generando una stringa SQL con un segnaposto param per ciascuno dei valori, è più semplice generare subito l'SQL finale.
Nota che poiché i valori sono string
s, c'è posto per l'attacco SQL injection, quindi prima testiamo se tutte le string
i valori sono infatti numeri, e procediamo solo in tal caso:
tags := []string{"1", "2", "3"}
buf := bytes.NewBufferString("SELECT COUNT(id) FROM tags WHERE id IN(")
for i, v := range tags {
if i > 0 {
buf.WriteString(",")
}
if _, err := strconv.Atoi(v); err != nil {
panic("Not number!")
}
buf.WriteString(v)
}
buf.WriteString(")")
Eseguendo:
num := 0
if err := Db.QueryRow(buf.String()).Scan(&num); err != nil {
log.Println(err)
}
Utilizzo di ANY
Puoi anche usare ANY
di Postgresql , la cui sintassi è la seguente:
expression operator ANY (array expression)
Usando questo, la nostra query potrebbe assomigliare a questa:
SELECT COUNT(id) FROM tags WHERE id = ANY('{1,2,3}'::int[])
In questo caso puoi dichiarare la forma del testo dell'array come parametro:
SELECT COUNT(id) FROM tags WHERE id = ANY($1::int[])
Che può essere semplicemente costruito in questo modo:
tags := []string{"1", "2", "3"}
param := "{" + strings.Join(tags, ",") + "}"
Tieni presente che in questo caso non è richiesto alcun controllo poiché l'espressione dell'array non consentirà l'iniezione SQL (ma risulterà in un errore di esecuzione della query).
Quindi il codice completo:
tags := []string{"1", "2", "3"}
q := "SELECT COUNT(id) FROM tags WHERE id = ANY($1::int[])"
param := "{" + strings.Join(tags, ",") + "}"
num := 0
if err := Db.QueryRow(q, param).Scan(&num); err != nil {
log.Println(err)
}