क्या इनलाइन एसक्यूएल अभी भी बुरे अभ्यास के रूप में वर्गीकृत है जो हमारे पास माइक्रो ओआरएम है?


26

यह एक खुले समाप्त प्रश्न का एक सा है, लेकिन मैं कुछ राय चाहता था, जैसा कि मैं एक ऐसी दुनिया में बड़ा हुआ जहां इनलाइन SQL स्क्रिप्ट आदर्श थे, फिर हम सभी SQL इंजेक्शन आधारित मुद्दों के बारे में बहुत जागरूक थे, और sql कितना नाजुक था जब सभी स्थानों पर स्ट्रिंग जोड़तोड़ कर रहा है।

फिर ओआरएम की सुबह आई, जहां आप ओआरएम को क्वेरी समझा रहे थे और इसे अपनी स्वयं की एसक्यूएल उत्पन्न करने दे रहे थे, जो कि बहुत सारे मामलों में इष्टतम नहीं थी, लेकिन सुरक्षित और आसान थी। ORMs या डेटाबेस एब्स्ट्रक्शन लेयर्स के बारे में एक और अच्छी बात यह थी कि SQL को उसके डेटाबेस इंजन को ध्यान में रखते हुए जनरेट किया गया था, इसलिए मैं MSSQL, MYSQL के साथ Hibernate / Nhibernate का उपयोग कर सकता था और मेरा कोड कभी नहीं बदला यह सिर्फ एक कॉन्फिगरेशन डिटेल है।

अब वर्तमान दिन के लिए तेजी से आगे बढ़ें, जहां माइक्रो ओआरएम अधिक डेवलपर्स पर जीतते दिख रहे हैं मैं सोच रहा था कि हमने पूरे इन-लाइन एसक्यूएल विषय पर यू-टर्न क्यों लिया है।

मुझे स्वीकार करना चाहिए कि मुझे कोई ओआरएम कॉन्फिग फाइलों का विचार पसंद है और अपनी क्वेरी को अधिक इष्टतम तरीके से लिखने में सक्षम हूं, लेकिन ऐसा महसूस होता है कि मैं खुद को पुरानी कमजोरियों जैसे एसक्यूएल इंजेक्शन के लिए वापस खोल रहा हूं और मैं खुद को बांध रहा हूं एक डेटाबेस इंजन तो अगर मैं चाहता हूं कि मेरा सॉफ्टवेयर कई डेटाबेस इंजनों का समर्थन करे तो मुझे कुछ और स्ट्रिंग हैकरी करने की आवश्यकता होगी जो तब लगता है कि कोड को अपठनीय और अधिक नाजुक बनाना शुरू करें। (इससे पहले कि कोई इसका उल्लेख करे, मुझे पता है कि आप अधिकांश माइक्रो ऑर्म्स के साथ पैरामीटर आधारित तर्कों का उपयोग कर सकते हैं, जो एसक्यूएल टैबलेट पीसी से ज्यादातर मामलों में सुरक्षा प्रदान करता है।

तो इस तरह की बातों पर लोगों की क्या राय है? मैं इस उदाहरण में अपने माइक्रो ओआरएम के रूप में डैपर का उपयोग कर रहा हूं और एनबीबर्नेट इस परिदृश्य में मेरे नियमित ओआरएम के रूप में उपयोग कर रहा हूं, हालांकि प्रत्येक क्षेत्र में अधिकांश समान हैं।

मैं इनलाइन एसक्यूएल के रूप में क्या कहता हूंस्रोत कोड के भीतर SQL स्ट्रिंग्स है। स्रोत कोड में एसक्यूएल स्ट्रिंग्स पर डिजाइन की बहस का इस्तेमाल किया जाता था, जो तर्क के मूल इरादे से अलग होता है, यही वजह है कि सांख्यिकीय रूप से टाइप किए गए लिनक शैली के सवाल अभी भी सिर्फ 1 भाषा में लोकप्रिय हैं, लेकिन आपको एक पृष्ठ में C # और Sql कहने की सुविधा देता है अब आपके कच्चे स्रोत कोड में 2 भाषाएं परस्पर जुड़ी हुई हैं। बस स्पष्ट करने के लिए, SQL इंजेक्शन sql स्ट्रिंग्स का उपयोग करने के साथ ज्ञात मुद्दों में से एक है, मैं पहले से ही उल्लेख करता हूं कि आप इसे पैरामीटर आधारित प्रश्नों के साथ होने से रोक सकते हैं, हालांकि मैं अन्य प्रश्नों को हाइलाइट करता हूं जिसमें SQL प्रश्न आपके स्रोत कोड में शामिल हैं, जैसे DB वेंडर अमूर्त की कमी के साथ-साथ स्ट्रिंग आधारित प्रश्नों पर कब्जा करने में संकलित समय त्रुटि के किसी भी स्तर को खोने, ये सभी मुद्दे हैं जो हम ORM के साथ अपने उच्च स्तर की क्वेरी कार्यक्षमता के साथ कदमताल करने में कामयाब रहे,

इसलिए मैं व्यक्तिगत हाइलाइट किए गए मुद्दों पर कम ध्यान केंद्रित कर रहा हूं और अधिक बड़ी तस्वीर यह है कि अब SQL स्ट्रिंग्स को फिर से सीधे अपने स्रोत कोड में प्राप्त करना अधिक स्वीकार्य हो गया है, क्योंकि अधिकांश माइक्रो ओआरएम इस तंत्र का उपयोग करते हैं।

यहां एक समान प्रश्न है, जिसमें कुछ अलग-अलग दृष्टिकोण हैं, हालांकि माइक्रो ऑर्म संदर्भ के बिना इनलाइन sql के बारे में अधिक है:

/programming/5303746/is-inline-sql-hard-coding


1
क्या आपको लगता है कि आप प्रश्न को इस तरह से फिर से जोड़ सकते हैं कि यह एक राय नहीं पूछ रहा है? राय के लिए मतदान स्टैक एक्सचेंज के प्रश्नोत्तर प्रारूप में अच्छी तरह से फिट नहीं होता है।

आप हमेशा एक अलग वर्ग में अपने "माइक्रो ओआरएम" प्रश्नों को सार कर सकते हैं, जहां आवश्यक होने पर आप अपने डीबीएमएस को बदलने के रूप में निष्पादित होने वाले प्रश्नों को स्वैप करते हैं।
कोडकस्टर

"माइक्रो ओआरएम" शब्द नहीं सुना है। क्या आपका मतलब है कि ओआरएम पूरी तरह से एसक्यूएल को लेने का प्रयास नहीं करते हैं, या यह कुछ अलग है?
जेवियर

कोई बात नहीं, एक छोटे से googling के बाद, यह एक .net बात लगती है।
जेवियर

1
@GrandmasterB: एक उत्तर में क्यों समझाएँ। मैंने अपने जवाब में उस मुद्दे को बहुत दरकिनार कर दिया है, क्योंकि मेरा मानना ​​है कि यह एक व्यापार का सवाल है।
रॉबर्ट हार्वे

जवाबों:


31

जिसे आप "इनलाइन एसक्यूएल" के रूप में वर्णित कर रहे हैं, उसे वास्तव में "पैरामीटर के बिना स्ट्रिंग कॉन्सेप्टन" कहा जाना चाहिए, और आपको माइक्रो ओआरएम का सुरक्षित रूप से उपयोग करने के लिए ऐसा करने की आवश्यकता नहीं है।

इस डैपर उदाहरण पर विचार करें:

string sql = "SELECT * from user_profile WHERE FirstName LIKE @name;";
var result = connection.Query<Profile>(sql, new {name = "%"+name+"%"});

यह पूरी तरह से पैरामीटराइज्ड है, भले ही स्ट्रिंग कॉन्फैटिनेशन हो रहा हो। @ संकेत देखें?

या यह उदाहरण:

var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", 
          new { Age = (int?)null, Id = guid });

जो लगभग ADO.NET कोड के बराबर है:

List<Dog> dog = new List<Dog>();
using(var cmd = connection.CreateCommand()) {
    cmd.CommandText = "select Age = @Age, Id = @Id";
    cmd.Parameters.AddWithValue("Age", DBNull.Value);
    cmd.Parameters.AddWithValue("Id", guid);
    using(var reader = cmd.ExecuteReader()) {
        while(reader.Read()) {
            int age = reader.ReadInt32("Age");
            int id = reader.ReadInt32("Id");
            dog.Add(new Dog { Age = age, Id = id });
        }
    }
}

यदि आपको इससे अधिक लचीलेपन की आवश्यकता है, तो डैपर एसक्यूएल टेम्प्लेट और ए प्रदान करता है AddDynamicParms() फ़ंक्शन है। सभी SQL इंजेक्शन सुरक्षित।

तो पहली बार में SQL स्ट्रिंग्स का उपयोग क्यों करें?

ठीक है, उन्हीं कारणों से आप किसी अन्य ORM में कस्टम SQL का उपयोग करेंगे। हो सकता है कि ORM कोड-जनरेटिंग सब-इष्टतम SQL है, और आपको इसे ऑप्टिमाइज़ करने की आवश्यकता है। हो सकता है कि आप कुछ ऐसा करना चाहते हैं जो ओआरएम में मूल रूप से करना मुश्किल हो, जैसे कि यूनियन्स। या, शायद आप बस उन सभी प्रॉक्सी वर्गों को उत्पन्न करने की जटिलता से बचना चाहते हैं।

यदि आप वास्तव में Dapper (जो करता है?) में हर CRUD विधि के लिए SQL स्ट्रिंग नहीं लिखना चाहते हैं , तो आप इस लाइब्रेरी का उपयोग कर सकते हैं:

https://github.com/ericdc1/Dapper.SimpleCRUD/

यह आपको बेहद सरल और सीधा CRUD मिलेगा, जबकि अभी भी आपको हाथ से लिखे SQL कथनों का लचीलापन देता है। याद रखें, ऊपर दिया गया ADO.NET उदाहरण उसी तरह से था जैसा कि ORM के आने से पहले सभी ने किया था; डैपर उस पर सिर्फ एक पतली लिबास है।


अच्छे उदाहरण, मैंने पहले ही उल्लेख किया है कि आप मापदंडों के माध्यम से एसक्यूएल इंजेक्शन को रोक सकते हैं, क्योंकि यह बड़े सवाल का सिर्फ एक टुकड़ा है, इसमें एक एडिटिंग भी स्पष्ट किया गया है कि जब मैं इनलाइन एसक्यूएल शब्द का उपयोग करता हूं तो मेरा क्या अर्थ है ।
ग्रोफिट

मैंने अपने उत्तर में कुछ विवरण जोड़ा है।
रॉबर्ट हार्वे

2
SimpleCRUD की जानकारी के लिए +1 यह मौजूद नहीं था।
ग्रोफिट

Java में आपको Mybatis मिलेंगे जो कि Hibernate या EclipseLink की तुलना में जीवंत है और। इसका रास्ता एक्सएमएल में पूर्वनिर्धारित वाक्यों से है (कोड पर हार्डकोडिंग के बजाय)। यह अंतिम एसक्यूएल को बढ़ाने के लिए पूर्व शर्त के रूप में कुछ दिलचस्प सुविधाओं को भी जोड़ता है। हमने हाल ही में एक एपीआई वेब का उपयोग किया है जिसमें काफी उच्च संगति है और एक जटिल व्यवसाय नहीं है और इसने बहुत अच्छा काम किया है।
लाईव

2

मुझे sql बहुत पसंद है , और इसे स्ट्रिंग लिटरल्स में कटा हुआ देखकर खड़ा नहीं किया जा सकता है, इसलिए मैंने आपको c # प्रोजेक्ट्स में वास्तविक sql फाइलों के साथ काम करने देने के लिए थोड़ा VS एक्सटेंशन लिखा है। अपनी ही फाइल में sql का संपादन आपको कॉलम और टेबल, वाक्यविन्यास सत्यापन, परीक्षण निष्पादन, निष्पादन योजना और बाकी के लिए गहनता प्रदान करता है। जब आप फ़ाइल को सहेजते हैं, तो मेरा एक्सटेंशन c # आवरण वर्ग उत्पन्न करता है, इसलिए आप कभी भी कनेक्शन कोड, या कमांड कोड, या पैरामीटर या रीडर कोड की एक पंक्ति नहीं लिखते हैं। आपके प्रश्नों को सभी मानकीकृत किया गया है क्योंकि कोई अन्य तरीका नहीं है, और आपने अपने इनपुट मापदंडों और आपके परिणामों के लिए गहनता के साथ इकाई परीक्षण के लिए रिपॉजिटरी और पीओसीओ बनाए हैं।

और मैंने मुफ्त स्टेक चाकू में फेंक दिया है ... जब एक विशेषज्ञ को आपके डेवलपर के sql को आने और फिर से काम करने की आवश्यकता होती है, तो वह एक वास्तविक sql फ़ाइल देख रहा है, और किसी भी C # को छूने की आवश्यकता नहीं है। जब वह वापस जाती है और डीबी को छूती है, तो कुछ कॉलमों को हटाते हुए, गायब कॉलम के संदर्भ सीधे सी # में संकलित त्रुटियों के रूप में बाहर कूदते हैं। डेटाबेस आपके समाधान में एक अन्य परियोजना की तरह हो जाता है जिसे आप हैक कर सकते हैं, यह कोड में खोज योग्य है। यदि समाधान संकलित करता है, तो आप जानते हैं कि आपके सभी प्रश्न काम कर रहे हैं। अमान्य जातियों या अमान्य स्तंभ नामों, या अमान्य क्वेरी के कारण कोई रनटाइम त्रुटियाँ नहीं हैं।

डपर में वापस देखो, जो हम अभी भी काम में उपयोग कर रहे हैं, मैं विश्वास नहीं कर सकता कि 2016 में यह डेटा एक्सेस में सबसे अच्छी बात है। रनटाइम एमएसआईएल पीढ़ी सभी n चतुर है, लेकिन सभी त्रुटियां रनटाइम त्रुटियां हैं, और स्ट्रिंग हेरफेर, जैसे किसी अन्य उद्देश्य के लिए स्ट्रिंग हेरफेर, समय लेने वाली, नाजुक और त्रुटि प्रवण है। और अपने पोक्सो में अपने कॉलम के नामों को दोहराना कैसे सूखा हो सकता है, जिसे आपको लिखना है और हाथ से बनाए रखना है।

तो यह तूम गए वहाँ। यदि आप अपने खाली समय में (छोटे बच्चे और अन्य शौक के साथ) काम कर रहे अनसुने डेवलपर की अनचाही डेटा-तकनीक को देखना चाहते हैं, तो यह यहाँ पर है


आपको लगता है कि आपके छोटे से "नवाचार" के बारे में बहुत कुछ लगता है, लेकिन यह किसी भी तरह से कैसे अलग है, कहते हैं, ExecuteStoreQuery या ExecuteStoreCommand में Entity Framework?
रॉबर्ट हार्वे

मैं EF या SQL बहस में नहीं पड़ रहा हूँ। मेरी बात लोक के लिए है जो एसक्यूएल का उपयोग करना चाहते हैं। तो SQL निष्पादित करने के एक तरीके के रूप में, ExecuteStoreQuery () आपके लिए आपके POCOs को भर देगा, लेकिन आपको अभी भी चीजों की नज़र से, अपने POCO को परिभाषित करने की आवश्यकता है? और यह आपको एक फ़ाइल में sql डालने में मदद करने के लिए या अपने मापदंडों को बनाने के लिए कुछ भी नहीं करता है। आपकी क्वेरी कोड में खोज योग्य नहीं है, या परीक्षण योग्य नहीं है। कॉलम हटाने से आपके एप्लिकेशन में संकलित त्रुटियां उत्पन्न नहीं होंगी। मैं आगे बढ़ सकता हूं, लेकिन मुझे डर है कि मैं खुद को दोहरा रहा हूं :-) शायद आप यूट्यूब वीडियो देखने के लिए 3mins ले सकते हैं। यह फ्रेंच में है, ध्वनि नीचे करें! अंग्रेजी आ रही है।
bbsimonbb

EF POCO के सभी स्वचालित रूप से उत्पन्न करने में काफी सक्षम है। मुझे यहां क्या समझ नहीं आ रहा है? डैपर और बड़े पैमाने पर असली नवाचार यह है कि आपको POCO की बिल्कुल आवश्यकता नहीं है; आप बस उपयोग कर सकते हैं dynamic
रॉबर्ट हार्वे

मुझे ईएफ के बारे में लगभग कुछ नहीं पता है। ExecuteStoreQuery () एक इकाई को भरेगा। क्या यह क्वेरी से एक इकाई उत्पन्न करेगा । प्रविष्टियाँ DB ऑब्जेक्ट्स (या इसके विपरीत) से उत्पन्न होती हैं, प्रश्नों से नहीं। यदि आपकी क्वेरी किसी मौजूदा संस्था से मेल नहीं खाती है, तो आपको अपना POCO लिखना होगा, नहीं?
bbsimonbb

1
:-) मुझे कहना होगा कि मैं विज्ञापन के आरोपों के प्रति संवेदनशील हूं जब मैं अपना सर्वश्रेष्ठ विचार स्वतंत्र रूप से वहां रख रहा हूं। यहां मेरा नवीनतम सा आक्रामक व्यवसायवाद है। 3 मिनट के निशान से, आपको पता होना चाहिए कि मैं किसी चीज़ पर हूँ या नहीं।
bbsimonbb

1

इंजेक्शन के हमलों को रोकने के लिए क्वेरीज़ में क्या जाता है, इस पर पैरामीटर प्रश्नों के साथ-साथ रिपॉजिटरी डिज़ाइन पैटर्न आपको पूरा नियंत्रण देता है। इस मामले में इनलाइन एसक्यूएल बड़े और जटिल प्रश्नों के लिए पठनीयता के अलावा कोई मुद्दा नहीं है, जो किसी भी तरह संग्रहीत प्रक्रियाओं में होना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.