Förbygga SQL-frågan (förhindra SQL-injektion)
Om du genererar en SQL-sträng med en param-platshållare för vart och ett av värdena, är det lättare att bara generera den slutliga SQL-koden direkt.
Observera att eftersom värden är string
s, det finns plats för SQL-injektionsattack, så vi testar först om alla string
värden är verkligen siffror, och vi fortsätter bara om så är fallet:
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(")")
Utför det:
num := 0
if err := Db.QueryRow(buf.String()).Scan(&num); err != nil {
log.Println(err)
}
Använda ANY
Du kan också använda Postgresqls ANY
, vars syntax är följande:
expression operator ANY (array expression)
Med det kan vår fråga se ut så här:
SELECT COUNT(id) FROM tags WHERE id = ANY('{1,2,3}'::int[])
I det här fallet kan du deklarera arrayens textform som en parameter:
SELECT COUNT(id) FROM tags WHERE id = ANY($1::int[])
Som helt enkelt kan byggas så här:
tags := []string{"1", "2", "3"}
param := "{" + strings.Join(tags, ",") + "}"
Observera att ingen kontroll krävs i det här fallet eftersom array-uttrycket inte tillåter SQL-injektion (utan snarare kommer att resultera i ett frågekörningsfel).
Så hela koden:
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)
}