यदि संभव हो तो, ऐसा न करें।
इसका उत्तर है- यह एक प्रतिमान है। यदि क्लाइंट को उस तालिका का पता है, जिससे वह डेटा चाहता है, तो SELECT FROM ThatTable
। यदि एक डेटाबेस को इस तरह से डिज़ाइन किया गया है कि यह आवश्यक है, तो यह उप-आशावादी रूप से डिज़ाइन किया गया लगता है। यदि डेटा एक्सेस लेयर को यह जानना होगा कि क्या किसी टेबल में कोई वैल्यू मौजूद है, तो एसक्यूएल को उस कोड में बनाना आसान है, और इस कोड को डेटाबेस में पुश करना अच्छा नहीं है।
मेरे लिए यह एक एलेवेटर के अंदर एक उपकरण स्थापित करने जैसा लगता है जहां कोई वांछित मंजिल की संख्या में टाइप कर सकता है। गो बटन को दबाए जाने के बाद, यह वांछित तल के लिए सही बटन पर एक यांत्रिक हाथ ले जाता है और इसे दबाता है। यह कई संभावित मुद्दों का परिचय देता है।
कृपया ध्यान दें: यहाँ मजाक का कोई इरादा नहीं है। मेरा मूर्खतापूर्ण लिफ्ट उदाहरण था * इस तकनीक के साथ मुद्दों को इंगित करने के लिए मैं सबसे अच्छी डिवाइस * कल्पना कर सकता था। यह अस्पष्ट / विचित्र सर्वर-साइड SQL कोड का उपयोग करके एक कॉलर स्पेस (एक मजबूत और अच्छी तरह से समझे गए डीएसएल, एसक्यूएल का उपयोग करके) से अप्रत्यक्ष की एक बेकार परत चलती है।
डायनेमिक SQL में क्वेरी कंस्ट्रक्शन लॉजिक के मूवमेंट के माध्यम से ऐसी जिम्मेदारी-बंटवारा कोड को समझने में कठिन बनाता है। यह एक मानक और विश्वसनीय कन्वेंशन का उल्लंघन करता है (कैसे एक SQL क्वेरी चुनता है कि क्या चुनना है) कस्टम कोड के नाम पर त्रुटि के लिए संभावित।
इस दृष्टिकोण के साथ कुछ संभावित समस्याओं पर यहां विस्तृत बिंदु दिए गए हैं:
डायनेमिक एसक्यूएल एसक्यूएल इंजेक्शन की संभावना प्रदान करता है जो कि फ्रंट एंड कोड या बैक एंड कोड को पहचानना मुश्किल होता है (किसी को यह देखने के लिए उन्हें एक साथ निरीक्षण करना होगा)।
संग्रहीत कार्यविधियाँ और फ़ंक्शन उन संसाधनों तक पहुँच सकते हैं जो SP / फ़ंक्शन स्वामी के पास अधिकार हैं, लेकिन कॉलर नहीं करता है। जहां तक मैं समझता हूं, विशेष देखभाल के बिना, तब डिफ़ॉल्ट रूप से जब आप डायनेमिक SQL बनाने वाले कोड का उपयोग करते हैं और इसे चलाते हैं, तो डेटाबेस कॉलर के अधिकारों के तहत डायनेमिक SQL निष्पादित करता है। इसका मतलब है कि आप या तो विशेषाधिकार प्राप्त वस्तुओं का उपयोग करने में सक्षम नहीं होंगे, या आपको उन्हें सभी क्लाइंट तक खोलना होगा, जिससे विशेषाधिकारित डेटा पर संभावित हमले की सतह क्षेत्र बढ़ेगा। निर्माण समय पर SP / फ़ंक्शन को सेट करना हमेशा किसी विशेष उपयोगकर्ता (SQL सर्वर में EXECUTE AS
) के रूप में चलता है, जो उस समस्या को हल कर सकता है, लेकिन चीजों को और अधिक जटिल बनाता है। यह पिछले बिंदु में वर्णित SQL इंजेक्शन के जोखिम को बढ़ाता है, गतिशील SQL को बहुत मोहक हमला वेक्टर बनाता है।
जब एक डेवलपर को यह समझना चाहिए कि इसे संशोधित करने या बग को ठीक करने के लिए एप्लिकेशन कोड क्या कर रहा है, तो उसे सटीक SQL क्वेरी को निष्पादित करने में मुश्किल होगी। SQL प्रोफाइलर का उपयोग किया जा सकता है, लेकिन यह विशेष विशेषाधिकार लेता है और उत्पादन प्रणालियों पर नकारात्मक प्रदर्शन प्रभाव डाल सकता है। निष्पादित क्वेरी को एसपी द्वारा लॉग किया जा सकता है लेकिन इससे संदिग्ध लाभ के लिए जटिलता बढ़ जाती है (नए तालिकाओं को समायोजित करने, पुराने डेटा को शुद्ध करने आदि की आवश्यकता होती है) और यह काफी गैर-स्पष्ट है। वास्तव में, कुछ एप्लिकेशन ऐसे होते हैं जैसे कि डेवलपर के पास डेटाबेस क्रेडेंशियल्स नहीं होते हैं, इसलिए उसके लिए वास्तव में क्वेरी सबमिट किए जाने को देखना लगभग असंभव हो जाता है।
जब कोई त्रुटि होती है, जैसे कि जब आप ऐसी तालिका का चयन करने का प्रयास करते हैं जो मौजूद नहीं है, तो आपको डेटाबेस से "अमान्य ऑब्जेक्ट नाम" की तर्ज पर एक संदेश मिलेगा। यह ठीक वैसा ही होगा कि आप एसक्यूएल को बैक एंड या डेटाबेस में कंपोज कर रहे हैं, लेकिन अंतर यह है कि सिस्टम के समस्या निवारण की कोशिश कर रहे कुछ खराब डेवलपर को एक लेवल और गहरा करना पड़ता है, जहां नीचे एक और गुफा होती है। समस्या मौजूद है, आश्चर्य-प्रक्रिया में खुदाई करने के लिए जो यह सब पता लगाने की कोशिश करता है कि समस्या क्या है। लॉग "GetWidget में त्रुटि" नहीं दिखाएंगे, यह "OneProcedureToRuleThemAllRunner में त्रुटि" दिखाएगा। यह अमूर्तता आमतौर पर एक प्रणाली को बदतर बना देगी ।
एक पैरामीटर के आधार पर स्विचिंग टेबल नामों के छद्म सी # में एक उदाहरण:
string sql = $"SELECT * FROM {EscapeSqlIdentifier(tableName)};"
results = connection.Execute(sql);
हालांकि यह कल्पना करने योग्य हर संभव मुद्दे को समाप्त नहीं करता है, लेकिन दूसरी तकनीक के साथ मैं जिन खामियों को रेखांकित करता हूं, वे इस उदाहरण से अनुपस्थित हैं।