वहां क्या चल रहा है?
आप Add
. के कई अधिभार के लिए पैरामीटर सूचियों को उद्धृत करते हैं . ये सुविधाजनक तरीके हैं जो सीधे SqlParameter
. के कंस्ट्रक्टर ओवरलोड से मेल खाते हैं कक्षा। वे अनिवार्य रूप से पैरामीटर ऑब्जेक्ट का निर्माण करते हैं, जिस भी कंस्ट्रक्टर के पास आपके द्वारा कॉल की जाने वाली सुविधा विधि के समान हस्ताक्षर होते हैं, और फिर SqlParameterCollection.Add(SqlParameter)
पर कॉल करते हैं। इस तरह:
SqlParameter foo = new SqlParameter(parameterName, dbType, size);
this.Add(foo);
AddWithValue
समान है, लेकिन आगे भी सुविधा लेता है, मूल्य भी निर्धारित करता है। हालाँकि, यह वास्तव में एक रूपरेखा दोष को हल करने के लिए पेश किया गया था। MSDN को उद्धृत करने के लिए,
Add
. का अधिभार यह स्ट्रिंग लेता है और SqlParameterCollection.Add
के साथ संभावित अस्पष्टता के कारण एक ऑब्जेक्ट को हटा दिया गया था। अधिभारजो एक String
लेता है और एक SqlDbType
एन्यूमरेशन वैल्यू जहां स्ट्रिंग के साथ एक पूर्णांक पास करने की व्याख्या या तो पैरामीटर मान या संबंधित SqlDbType
के रूप में की जा सकती है मूल्य। AddWithValue
का उपयोग करें जब भी आप उसका नाम और मान निर्दिष्ट करके कोई पैरामीटर जोड़ना चाहते हैं।
कंस्ट्रक्टर SqlParameter
के लिए ओवरलोड करता है क्लास इंस्टेंस गुण सेट करने के लिए केवल उपयुक्तताएं हैं। वे प्रदर्शन पर मामूली प्रभाव के साथ कोड को छोटा करते हैं:निर्माता सेटर विधियों को बायपास कर सकता है और सीधे निजी सदस्यों पर काम कर सकता है। अगर कोई अंतर है तो यह ज्यादा नहीं होगा।
मुझे क्या करना चाहिए?
निम्नलिखित पर ध्यान दें (एमएसडीएन से)
<ब्लॉकक्वॉट>
द्विदिश और आउटपुट पैरामीटर, और वापसी मान के लिए, आपको Size
का मान सेट करना होगा . इनपुट पैरामीटर के लिए यह आवश्यक नहीं है, और यदि स्पष्ट रूप से सेट नहीं किया गया है, तो मान निर्दिष्ट पैरामीटर के वास्तविक आकार से अनुमानित किया जाता है जब पैरामीटरयुक्त कथन निष्पादित किया जाता है।
डिफ़ॉल्ट प्रकार इनपुट है। हालांकि, यदि आप आकार को इस तरह अनुमानित करने की अनुमति देते हैं और आप पैरामीटर ऑब्जेक्ट को लूप में रीसायकल करते हैं (आपने कहा था कि आप प्रदर्शन से चिंतित थे) तो आकार पहले मान द्वारा निर्धारित किया जाएगा और बाद में कोई भी मान जो लंबे समय तक होगा काटा हुआ। स्पष्ट रूप से यह केवल चर लंबाई मानों जैसे स्ट्रिंग्स के लिए महत्वपूर्ण है।
यदि आप एक ही तार्किक पैरामीटर को बार-बार लूप में पास कर रहे हैं, तो मैं आपको लूप के बाहर एक SqlParameter ऑब्जेक्ट बनाने और इसे उचित रूप से आकार देने की सलाह देता हूं। एक वर्चर को ओवर-साइज़ करना हानिरहित है, इसलिए यदि यह सटीक अधिकतम प्राप्त करने के लिए एक पिटा है, तो इसे कॉलम की अपेक्षा से कहीं अधिक बड़ा सेट करें। चूंकि आप प्रत्येक पुनरावृत्ति के लिए एक नई वस्तु बनाने के बजाय वस्तु का पुनर्चक्रण कर रहे हैं, लूप की अवधि में स्मृति खपत गिरावट होने की संभावना है भले ही आप ओवरसाइज़िंग से थोड़ा उत्साहित हों।
सच कहा जाए, जब तक आप हजारों कॉलों को संसाधित नहीं करते हैं, तब तक इनमें से किसी से भी बहुत फर्क नहीं पड़ेगा। AddWithValue
आकार की समस्या को दूर करते हुए एक नई वस्तु बनाता है। यह छोटा और मीठा और समझने में आसान है। यदि आप हजारों में से लूप करते हैं, तो मेरे दृष्टिकोण का उपयोग करें। यदि आप नहीं करते हैं, तो AddWithValue
. का उपयोग करें अपने कोड को सरल और बनाए रखने में आसान रखने के लिए।
2008 बहुत समय पहले था
जब से मैंने इसे लिखा है, इतने सालों में दुनिया बदल गई है। नए प्रकार की तिथियां हैं, और एक समस्या भी है जो मेरे दिमाग में तब तक नहीं आई जब तक कि तारीखों के साथ हाल की समस्या ने मुझे चौड़ीकरण के प्रभावों के बारे में सोचने पर मजबूर नहीं किया।
शर्तों से अपरिचित लोगों के लिए, चौड़ा करना और संकुचित करना, डेटा प्रकार रूपांतरणों के गुण हैं। यदि आप एक डबल को एक इंट असाइन करते हैं, तो सटीकता का कोई नुकसान नहीं होता है क्योंकि डबल "व्यापक" होता है। ऐसा करना हमेशा सुरक्षित होता है, इसलिए रूपांतरण स्वचालित होता है। यही कारण है कि आप एक int को एक डबल में असाइन कर सकते हैं लेकिन दूसरी तरफ आपको एक स्पष्ट कास्ट करना है - डबल से int परिशुद्धता के संभावित नुकसान के साथ एक संकुचित रूपांतरण है।
यह स्ट्रिंग्स पर लागू हो सकता है:NVARCHAR VARCHAR से बड़ा है, इसलिए आप एक NVARCHAR को VARCHAR असाइन कर सकते हैं लेकिन दूसरी तरफ जाने के लिए एक कास्ट की आवश्यकता होती है। तुलना काम करती है क्योंकि VARCHAR परोक्ष रूप से NVARCHAR तक विस्तृत होता है, लेकिन यह अनुक्रमणिका के उपयोग में हस्तक्षेप करेगा!
सी # तार यूनिकोड हैं, इसलिए AddWithValue एक NVARCHAR पैरामीटर उत्पन्न करेगा। दूसरे छोर पर, VARCHAR स्तंभ मान तुलना के लिए NVARCHAR तक विस्तृत होते हैं। यह क्वेरी निष्पादन को नहीं रोकता है लेकिन यह अनुक्रमणिका को उपयोग होने से रोकता है। यह बुरा है।
आप इसके बारे में क्या कर सकते हैं? आपके पास दो संभावित समाधान हैं।
- स्पष्ट रूप से पैरामीटर टाइप करें। इसका मतलब अब AddWithValue नहीं है
- सभी स्ट्रिंग कॉलम प्रकारों को NVARCHAR में बदलें।
VARCHAR को छोड़ना शायद सबसे अच्छा विचार है। यह पूर्वानुमेय परिणामों के साथ एक साधारण परिवर्तन है और यह आपके स्थानीयकरण की कहानी को बेहतर बनाता है। हालाँकि, आपके पास यह एक विकल्प के रूप में नहीं हो सकता है।
इन दिनों मैं बहुत अधिक प्रत्यक्ष ADO.NET नहीं करता। Linq2Sql अब मेरी पसंद का हथियार है, और इस अद्यतन को लिखने के कार्य ने मुझे आश्चर्यचकित कर दिया है कि यह इस समस्या को कैसे संभालता है। VARCHAR कॉलम के माध्यम से लुकअप के लिए मेरे डेटा एक्सेस कोड की जांच करने की अचानक, ज्वलंत इच्छा है।
2019 और दुनिया आगे बढ़ गई है फिर से
Linq2Sql डॉटनेट कोर में उपलब्ध नहीं है, इसलिए मैं खुद को डैपर का उपयोग कर पाता हूं। [एन] वचरर समस्या अभी भी एक चीज है लेकिन यह अब तक दफन नहीं है। मेरा मानना है कि कोई भी एडीओ का उपयोग कर सकता है इसलिए इस संबंध में चीजें पूरी तरह से आ गई हैं।