Tạo trước truy vấn SQL (ngăn chặn việc đưa vào SQL)
Nếu bạn đang tạo một chuỗi SQL có trình giữ chỗ tham số cho mỗi giá trị, thì việc tạo SQL cuối cùng ngay lập tức sẽ dễ dàng hơn.
Lưu ý rằng vì các giá trị là string
s, có chỗ cho cuộc tấn công chèn SQL, vì vậy trước tiên chúng tôi kiểm tra xem tất cả chuỗi string
các giá trị thực sự là số và chúng tôi chỉ tiến hành nếu vậy:
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(")")
Đang thực thi nó:
num := 0
if err := Db.QueryRow(buf.String()).Scan(&num); err != nil {
log.Println(err)
}
Sử dụng ANY
Bạn cũng có thể sử dụng ANY
của Postgresql , có cú pháp như sau:
expression operator ANY (array expression)
Sử dụng điều đó, truy vấn của chúng tôi có thể trông giống như sau:
SELECT COUNT(id) FROM tags WHERE id = ANY('{1,2,3}'::int[])
Trong trường hợp này, bạn có thể khai báo dạng văn bản của mảng dưới dạng tham số:
SELECT COUNT(id) FROM tags WHERE id = ANY($1::int[])
Đơn giản có thể được xây dựng như thế này:
tags := []string{"1", "2", "3"}
param := "{" + strings.Join(tags, ",") + "}"
Lưu ý rằng không cần kiểm tra trong trường hợp này vì biểu thức mảng sẽ không cho phép đưa vào SQL (mà còn dẫn đến lỗi thực thi truy vấn).
Vì vậy, mã đầy đủ:
Các thẻ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)
}