Vooraf bouwen van de SQL-query (voorkomen van SQL-injectie)
Als u een SQL-tekenreeks genereert met een tijdelijke aanduiding voor een parameter voor elk van de waarden, is het gemakkelijker om meteen de definitieve SQL te genereren.
Merk op dat aangezien waarden string
zijn s, er is plaats voor SQL-injectie-aanvallen, dus we testen eerst of alle string
waarden zijn inderdaad getallen, en we gaan alleen verder als dat zo is:
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(")")
Uitvoeren:
num := 0
if err := Db.QueryRow(buf.String()).Scan(&num); err != nil {
log.Println(err)
}
ANY
gebruiken
U kunt ook ANY
. van Postgresql gebruiken , waarvan de syntaxis als volgt is:
expression operator ANY (array expression)
Als we dat gebruiken, kan onze vraag er als volgt uitzien:
SELECT COUNT(id) FROM tags WHERE id = ANY('{1,2,3}'::int[])
In dit geval kunt u de tekstvorm van de array als parameter declareren:
SELECT COUNT(id) FROM tags WHERE id = ANY($1::int[])
Die eenvoudig als volgt kan worden gebouwd:
tags := []string{"1", "2", "3"}
param := "{" + strings.Join(tags, ",") + "}"
Merk op dat er in dit geval geen controle nodig is, aangezien de array-expressie geen SQL-injectie toestaat (maar eerder zal resulteren in een uitvoeringsfout van de query).
Dus de volledige code:
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)
}