Membuat kueri SQL sebelumnya (mencegah injeksi SQL)
Jika Anda membuat string SQL dengan placeholder param untuk setiap nilai, lebih mudah untuk langsung membuat SQL final.
Perhatikan bahwa karena nilainya adalah string
s, ada tempat untuk serangan injeksi SQL, jadi pertama-tama kita uji apakah semua string
nilai memang angka, dan kami hanya melanjutkan jika demikian:
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(")")
Menjalankannya:
num := 0
if err := Db.QueryRow(buf.String()).Scan(&num); err != nil {
log.Println(err)
}
Menggunakan ANY
Anda juga dapat menggunakan ANY
. Postgresql , yang sintaksnya adalah sebagai berikut:
expression operator ANY (array expression)
Dengan menggunakan itu, kueri kita mungkin terlihat seperti ini:
SELECT COUNT(id) FROM tags WHERE id = ANY('{1,2,3}'::int[])
Dalam hal ini Anda dapat mendeklarasikan bentuk teks dari array sebagai parameter:
SELECT COUNT(id) FROM tags WHERE id = ANY($1::int[])
Yang hanya dapat dibangun seperti ini:
tags := []string{"1", "2", "3"}
param := "{" + strings.Join(tags, ",") + "}"
Perhatikan bahwa tidak ada pemeriksaan yang diperlukan dalam kasus ini karena ekspresi array tidak akan mengizinkan injeksi SQL (tetapi akan menghasilkan kesalahan eksekusi kueri).
Jadi kode lengkapnya:
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)
}