प्लेसहोल्डर ('?'
) का उपयोग केवल फ़िल्टर पैरामीटर के लिए गतिशील, बच निकले मान डालने के लिए किया जा सकता है (उदा. WHERE
में भाग), जहां डेटा मान प्रकट होने चाहिए, SQL कीवर्ड, पहचानकर्ताओं आदि के लिए नहीं। आप इसका उपयोग आदेश द्वारा
को गतिशील रूप से निर्दिष्ट करने के लिए नहीं कर सकते हैं या ग्रुप बाय
मान।
हालांकि आप इसे अभी भी कर सकते हैं, उदाहरण के लिए आप fmt.Sprintf()का उपयोग कर सकते हैं। कोड>
डायनामिक क्वेरी टेक्स्ट को इस तरह से असेंबल करने के लिए:
ordCol := "title"
qtext := fmt.Sprintf("SELECT * FROM Apps ORDER BY %s DESC", ordCol)
rows, err := db.Query(qtext)
ध्यान रखने योग्य बातें:
ऐसा करने से आपको मैन्युअल रूप से बनाम SQL इंजेक्शन का बचाव करना होगा, उदा। यदि कॉलम नाम का मान उपयोगकर्ता से आता है, तो आप किसी भी मूल्य को स्वीकार नहीं कर सकते हैं और इसे सीधे क्वेरी में सम्मिलित कर सकते हैं अन्यथा उपयोगकर्ता सभी प्रकार के बुरे काम कर सकेगा। सामान्य तौर पर आपको केवल अंग्रेजी वर्णमाला के अक्षर + अंक + अंडरस्कोर ('_'
स्वीकार करना चाहिए। )।
एक पूर्ण, व्यापक चेकर या एस्केपिंग फ़ंक्शन प्रदान करने का प्रयास किए बिना, आप इस सरल रेगेक्सपी का उपयोग कर सकते हैं जो केवल अंग्रेजी अक्षरों, अंकों और '_'
को स्वीकार करता है। :
valid := regexp.MustCompile("^[A-Za-z0-9_]+$")
if !valid.MatchString(ordCol) {
// invalid column name, do not proceed in order to prevent SQL injection
}
उदाहरण (इसे गो प्लेग्राउंड पर आज़माएं ):
fmt.Println(valid.MatchString("title")) // true
fmt.Println(valid.MatchString("another_col_2")) // true
fmt.Println(valid.MatchString("it's a trap!")) // false
fmt.Println(valid.MatchString("(trap)")) // false
fmt.Println(valid.MatchString("also*trap")) // false