SQL क्वेरी को प्री-बिल्डिंग (SQL इंजेक्शन को रोकना)
यदि आप प्रत्येक मान के लिए एक परम प्लेसहोल्डर के साथ एक SQL स्ट्रिंग जनरेट कर रहे हैं, तो फ़ाइनल SQL को तुरंत जनरेट करना आसान हो जाता है।
ध्यान दें कि चूंकि मान string
हैं s, SQL इंजेक्शन हमले के लिए जगह है, इसलिए हम पहले परीक्षण करते हैं कि क्या सभी string
मान वास्तव में संख्याएं हैं, और हम केवल तभी आगे बढ़ते हैं यदि ऐसा है:
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(")")
इसे निष्पादित करना:
num := 0
if err := Db.QueryRow(buf.String()).Scan(&num); err != nil {
log.Println(err)
}
ANY
का उपयोग करना
आप Postgresql के ANY
. का भी उपयोग कर सकते हैं , जिसका सिंटैक्स इस प्रकार है:
expression operator ANY (array expression)
इसका उपयोग करके, हमारी क्वेरी कुछ इस तरह दिख सकती है:
SELECT COUNT(id) FROM tags WHERE id = ANY('{1,2,3}'::int[])
इस मामले में आप सरणी के टेक्स्ट फॉर्म को पैरामीटर के रूप में घोषित कर सकते हैं:
SELECT COUNT(id) FROM tags WHERE id = ANY($1::int[])
जिसे आसानी से इस तरह बनाया जा सकता है:
tags := []string{"1", "2", "3"}
param := "{" + strings.Join(tags, ",") + "}"
ध्यान दें कि इस मामले में किसी जांच की आवश्यकता नहीं है क्योंकि सरणी अभिव्यक्ति SQL इंजेक्शन की अनुमति नहीं देगी (बल्कि इसके परिणामस्वरूप क्वेरी निष्पादन त्रुटि होगी)।
तो पूरा कोड:
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)
}