हां, हार्ड कोडिंग एसक्यूएल स्ट्रिंग्स को एप्लिकेशन कोड में आमतौर पर एक विरोधी पैटर्न है।
आइए इसे उत्पादन कोड में देखने के वर्षों से विकसित सहिष्णुता को अलग करने की कोशिश करें। एक ही फ़ाइल में अलग-अलग वाक्यविन्यास के साथ पूरी तरह से अलग-अलग भाषाओं को मिलाकर आम तौर पर एक वांछनीय विकास तकनीक नहीं है। यह रेजर जैसी टेम्प्लेट भाषाओं से अलग है जो कई भाषाओं को प्रासंगिक अर्थ देने के लिए डिज़ाइन की गई हैं। जैसा कि सावा बी नीचे एक टिप्पणी में उल्लेख करता है, एसक्यूएल आपकी सी # या अन्य एप्लिकेशन भाषा (पायथन, सी ++, आदि) में किसी भी अन्य की तरह एक स्ट्रिंग है और शब्दार्थ अर्थहीन है। ज्यादातर मामलों में एक से अधिक भाषा को मिलाते समय यही बात लागू होती है, हालांकि स्पष्ट रूप से ऐसी स्थितियां हैं जहां ऐसा करना स्वीकार्य है, जैसे कि सी में इनलाइन असेंबली, HTML में सीएसएस के छोटे और बोधगम्य स्निपेट (ध्यान दें कि सीएसएस को HTML के साथ मिलाने के लिए बनाया गया है। ), और दूसरे।
(रॉबर्ट सी। मार्टिन को भाषाओं के मिश्रण पर, क्लीन कोड , अध्याय 17, "कोड स्मेल एंड हेयूरिस्टिक्स", पृष्ठ 288)
इस प्रतिक्रिया के लिए, मैं एसक्यूएल पर ध्यान केंद्रित करूंगा (जैसा कि प्रश्न में पूछा गया है)। निम्नलिखित मुद्दे तब हो सकते हैं जब SQL को असंतुष्ट तारों के एक ला कार्टे सेट के रूप में संग्रहीत किया जाता है:
- डेटाबेस लॉजिक का पता लगाना मुश्किल है। आप अपने सभी SQL स्टेटमेंट को खोजने के लिए क्या खोजते हैं? "SELECT", "UPDATE", "MERGE", आदि के साथ स्ट्रिंग्स?
- उसी या समान एसक्यूएल का उपयोग करना मुश्किल हो जाता है।
- अन्य डेटाबेस के लिए समर्थन जोड़ना मुश्किल है। कोई इसे कैसे पूरा करेगा? प्रत्येक डेटाबेस के लिए if..then स्टेटमेंट जोड़ें और विधि में स्ट्रिंग्स के रूप में सभी प्रश्नों को संग्रहीत करें?
- डेवलपर्स किसी अन्य भाषा में एक बयान पढ़ते हैं और विधि के उद्देश्य से विधि के कार्यान्वयन विवरण (कैसे और कहां से डेटा पुनर्प्राप्त किया जाता है) पर ध्यान केंद्रित करते हुए बदलाव से विचलित हो जाते हैं।
- हालांकि एक-लाइनर एक समस्या का बहुत अधिक नहीं हो सकता है, क्योंकि स्टेटमेंट अधिक जटिल हो जाते हैं, इनलाइन एसक्यूएल तार टूटने लगते हैं। 113 लाइन स्टेटमेंट के साथ आप क्या करते हैं? अपनी विधि में सभी 113 लाइनें डालें?
- डेवलपर अपने SQL संपादक (SSMS, SQL डेवलपर, आदि) और उनके स्रोत कोड के बीच प्रश्नों को कुशलतापूर्वक कैसे आगे बढ़ाता है? C # का
@
उपसर्ग आसान बनाता है, लेकिन मैंने बहुत सारे कोड देखे हैं जो प्रत्येक SQL लाइन को कोट करते हैं और नईलाइन्स से बच जाते हैं।
"SELECT col1, col2...colN"\
"FROM painfulExample"\
"WHERE maintainability IS NULL"\
"AND modification.effort > @necessary"\
- आस-पास के एप्लिकेशन कोड के साथ SQL को संरेखित करने के लिए उपयोग किए जाने वाले इंडेंटेशन वर्णों को प्रत्येक निष्पादन के साथ नेटवर्क पर प्रसारित किया जाता है। यह संभवतः छोटे पैमाने के अनुप्रयोगों के लिए नगण्य है, लेकिन यह सॉफ्टवेयर के उपयोग बढ़ने के साथ जोड़ सकता है।
पूर्ण ORMs (ऑब्जेक्ट-रिलेशनल मैपर्स जैसे कि एंटिटी फ्रेमवर्क या हाइबरनेट) एप्लिकेशन कोड में बेतरतीब ढंग से पेप्पर्ड एसक्यूएल को समाप्त कर सकते हैं। SQL और संसाधन फ़ाइलों का मेरा उपयोग एक उदाहरण है। ORMs, हेल्पर कक्षाएं, आदि सभी क्लीनर कोड के लक्ष्य को पूरा करने में मदद कर सकते हैं।
जैसा कि केविन ने पहले उत्तर में कहा था, कोड में एसक्यूएल छोटी परियोजनाओं में स्वीकार्य हो सकता है, लेकिन बड़ी परियोजनाएं छोटी परियोजनाओं के रूप में शुरू होती हैं, और प्रायिकता अधिकांश टीम वापस चली जाएगी और ऐसा करना सही होगा अक्सर कोड आकार के विपरीत आनुपातिक होता है।
प्रोजेक्ट में SQL को रखने के कई सरल तरीके हैं। उन विधियों में से एक जो मैं अक्सर उपयोग करता हूं, प्रत्येक एसक्यूएल स्टेटमेंट को विजुअल स्टूडियो रिसोर्स फाइल में डालना है, जिसे आमतौर पर "sql" नाम दिया गया है। एक पाठ फ़ाइल, JSON दस्तावेज़, या अन्य डेटा स्रोत आपके टूल के आधार पर उचित हो सकता है। कुछ मामलों में, एसक्यूएल स्ट्रिंग्स को सुनिश्चित करने के लिए समर्पित एक अलग वर्ग सबसे अच्छा विकल्प हो सकता है, लेकिन ऊपर वर्णित मुद्दों में से कुछ हो सकता है।
SQL उदाहरण: जो अधिक सुरुचिपूर्ण दिखता है ?:
using(DbConnection connection = Database.SystemConnection()) {
var eyesoreSql = @"
SELECT
Viewable.ViewId,
Viewable.HelpText,
PageSize.Width,
PageSize.Height,
Layout.CSSClass,
PaginationType.GroupingText
FROM Viewable
LEFT JOIN PageSize
ON PageSize.Id = Viewable.PageSizeId
LEFT JOIN Layout
ON Layout.Id = Viewable.LayoutId
LEFT JOIN Theme
ON Theme.Id = Viewable.ThemeId
LEFT JOIN PaginationType
ON PaginationType.Id = Viewable.PaginationTypeId
LEFT JOIN PaginationMenu
ON PaginationMenu.Id = Viewable.PaginationMenuId
WHERE Viewable.Id = @Id
";
var results = connection.Query<int>(eyesoreSql, new { Id });
}
हो जाता है
using(DbConnection connection = Database.SystemConnection()) {
var results = connection.Query<int>(sql.GetViewable, new { Id });
}
एसक्यूएल हमेशा एक आसानी से मिल जाने वाली फाइल या फाइलों के समूह में सेट होता है, प्रत्येक एक वर्णनात्मक नाम के साथ होता है, जो यह बताता है कि यह क्या करता है, इसके बजाय प्रत्येक ऐसा करता है, जिसमें एक टिप्पणी के लिए स्थान होता है जो एप्लिकेशन कोड के प्रवाह को बाधित नहीं करेगा। :
यह सरल विधि एकान्त क्वेरी को निष्पादित करती है। मेरे अनुभव में, "विदेशी भाषा" के उपयोग के रूप में लाभ तराजू अधिक परिष्कृत होता है।
संसाधन फ़ाइल का मेरा उपयोग केवल एक उदाहरण है। भाषा (SQL इस मामले में) और प्लेटफॉर्म के आधार पर अलग-अलग तरीके अधिक उपयुक्त हो सकते हैं।
यह और अन्य तरीके उपरोक्त सूची को निम्नलिखित तरीके से हल करते हैं:
- डेटाबेस कोड का पता लगाना आसान है क्योंकि यह पहले से ही केंद्रीकृत है। बड़ी परियोजनाओं में, अलग-अलग फ़ाइलों में एसक्यूएल जैसे समूह, शायद नाम के एक फ़ोल्डर के तहत
SQL
।
- एक दूसरे, तीसरे, आदि डेटाबेस के लिए समर्थन आसान है। एक इंटरफ़ेस (या अन्य भाषा अमूर्त) बनाएं जो प्रत्येक डेटाबेस के अद्वितीय विवरणों को लौटाता है। प्रत्येक डेटाबेस के लिए कार्यान्वयन समान बयानों की तुलना में थोड़ा अधिक हो जाता है:
return SqlResource.DoTheThing;
सच है, ये कार्यान्वयन संसाधन को छोड़ सकते हैं और SQL को एक स्ट्रिंग में शामिल कर सकते हैं, लेकिन ऊपर कुछ (सभी नहीं) समस्याएं अभी भी सतह पर होंगी।
- Refactoring सरल है - बस उसी संसाधन का पुन: उपयोग करें। तुम भी कुछ प्रारूप बयान के साथ समय के विभिन्न DBMS सिस्टम के लिए एक ही संसाधन प्रविष्टि का उपयोग कर सकते हैं। मैं अक्सर ऐसा करता हूं।
- द्वितीयक भाषा का उपयोग वर्णनात्मक नामों का उपयोग कर सकता है, उदाहरण के लिए
sql.GetOrdersForAccount
अधिक उपयोग के बजायSELECT ... FROM ... WHERE...
- एसक्यूएल बयानों को उनके आकार और जटिलता की परवाह किए बिना एक पंक्ति में बुलाया जाता है।
- एसक्यूएल को एसएसएमएस और एसक्यूएल डेवलपर जैसे डेटाबेस टूल्स के बीच कॉपी और पेस्ट किया जा सकता है। कोई उद्धरण चिह्न नहीं। कोई पीछे की ओर नहीं। विशेष रूप से Visual Studio संसाधन संपादक के मामले में, एक क्लिक SQL कथन पर प्रकाश डालता है। CTRL + C और फिर इसे SQL एडिटर में पेस्ट करें।
किसी संसाधन में SQL का निर्माण त्वरित है, इसलिए SQL-इन-कोड के साथ संसाधन उपयोग को मिलाने के लिए बहुत कम प्रोत्साहन है।
चुने हुए तरीके के बावजूद, मैंने पाया है कि भाषाओं का मिश्रण आमतौर पर कोड की गुणवत्ता को कम करता है। मुझे उम्मीद है कि यहाँ वर्णित कुछ मुद्दे और समाधान डेवलपर्स को उपयुक्त होने पर इस कोड की गंध को खत्म करने में मदद करते हैं।