2011-12-02 9 views
20

मैंने कोड के एक टुकड़े में एक अजीब समस्या देखी जहां एक adhoc SQL क्वेरी अपेक्षित आउटपुट का उत्पादन नहीं कर रही थी, भले ही इसके पैरामीटर डेटा स्रोत में रिकॉर्ड मिलान करते थे। मैं तत्काल विंडो में निम्न परीक्षण अभिव्यक्ति डालने का फैसला किया:एसकल्प पैरामीटर नाम/मूल्य कन्स्ट्रक्टर 0 शून्य के रूप में क्यों व्यवहार करता है?

new SqlParameter("Test", 0).Value 

यह null का एक परिणाम है, जो मुझे मेरे सिर खरोंच छोड़ देता है दे दी है। ऐसा लगता है कि SqlParameter कन्स्ट्रक्टर ज़ीरो को नल के रूप में मानता है। निम्नलिखित कोड सही परिणाम उत्पन्न करता है:

SqlParameter testParam = new SqlParameter(); 
testParam.ParameterName = "Test"; 
testParam.Value = 0; 
// subsequent inspection shows that the Value property is still 0 

क्या कोई इस व्यवहार को समझा सकता है? क्या यह किसी भी तरह जानबूझकर है? यदि हां, तो यह संभावित रूप से बल्कि खतरनाक है ...

+0

इस विषय पर और पढ़ें: http://stackoverflow.com/questions/14224465/compiler-value-type-resolution-and-hardcoded-0-integer-values ​​ – RLH

उत्तर

24

के रूप में है कि निर्माता के लिए documentation में कहा गया है:

जब आप मूल्य पैरामीटर में एक वस्तु निर्दिष्ट करते हैं, SqlDbType माइक्रोसॉफ्ट .NET फ्रेमवर्क प्रकार से अनुमान लगाया जाता है वस्तु का।

पूर्णांक पैरामीटर मान निर्दिष्ट करने के लिए SqlParameter कन्स्ट्रक्टर के इस अधिभार का उपयोग करते समय सावधानी बरतें। चूंकि यह अधिभार Object प्रकार का मान लेता है, इसलिए मान को शून्य होने पर आपको अभिन्न मान को Object प्रकार में परिवर्तित करना होगा, क्योंकि निम्न C# उदाहरण दर्शाता है।

Parameter = new SqlParameter("@pname", (object)0); 

आप इस रूपांतरण प्रदर्शन नहीं करते हैं, तो संकलक मानता है कि आप SqlParameter(string, SqlDbType) निर्माता अधिभार कॉल करने के लिए कोशिश कर रहे हैं।

आप बस अपने मामले में सोचा था कि आप एक अलग कन्स्ट्रक्टर को बुला रहे थे।

इस का कारण यह है कि सी # पूर्णांक शाब्दिक 0 से एक निहित रूपांतरण प्रकारों (जो सिर्फ अभिन्न प्रकार के नीचे हैं) Enum के लिए अनुमति देता है, और यह अंतर्निहित रूपांतरण अधिभार संकल्प के लिए एक बेहतर मैच होने की (string, SqlDbType) निर्माता का कारण बनता है (string, object) कन्स्ट्रक्टर के लिए int से object को परिवर्तित करने के लिए आवश्यक मुक्केबाजी रूपांतरण की तुलना में।

यह एक समस्या हो जाएगा कभी नहीं जब आप एक intचर गुजरती हैं, भले ही उस चर के मूल्य 0 है (क्योंकि यह एक शून्य शाब्दिक नहीं है), या किसी अन्य अभिव्यक्ति प्रकार int है। यह तब भी नहीं होगा जब आप उपरोक्त के रूप में intobject स्पष्ट रूप से डाले हैं, क्योंकि तब केवल एक मिलान अधिभार है।

+0

मुझे यह समस्या हो रही थी और एक अलग समाधान की कोशिश की काम नहीं किया: प्रस्तावित 'पैरामीटर = नया एसक्यूएल पैरामीटर (" @ pname ", कनवर्ट। ToInt32 (0)); 'पैरामीटर = नया एसक्यूएल पैरामीटर (" @ pname ", (int) 0);' जो ' मैंने कोशिश नहीं की? – mortb

+0

@mortb, आपको इसके लिए भाषा की कल्पना से परामर्श करना होगा, लेकिन मेरा अनुमान यह होगा कि अधिभार रिज़ॉल्यूशन पहले मामले में सटीक टाइप की देखभाल करेगा लेकिन दूसरे में enums की अनुमति दे सकता है क्योंकि आप अभी भी एक शाब्दिक उत्तीर्ण हो रहे हैं 'int' टाइप करें। – Joey

+0

मुझे पता चला है कि क्यों: http://stackoverflow.com/questions/3153841/strange-possibly-wrong-c-sharp-compiler-behavior-with-method-overloading- और शाब्दिक 0 का हमेशा मूल्यांकन किया जाएगा एक संख्या के प्रकार से मिलान करते हुए अन्य नंबर नहीं होंगे। थोड़ा अस्पष्ट लगता है ... – mortb

5

अपने पैरामीटर को पास/जोड़ते समय टाइप किए गए डेटा का उपयोग करना अच्छा प्रथा है।

रास्ता नीचे आप नीचे के रूप में कार्य को पूरा कर सकते हैं:

स्ट्रिंग के लिए/varchar लिखे गए डेटा:

SqlParameter pVarchar = new SqlParameter 
        { 
         ParameterName = "Test", 
         SqlDbType = System.Data.SqlDbType.VarChar, 
         Value = string.Empty, 
        }; 

पूर्णांक के लिए लिखे गए डेटा:

SqlParameter pInt = new SqlParameter 
        { 
         ParameterName = "Test", 
         SqlDbType = System.Data.SqlDbType.Int, 
         Value = 0, 
        }; 

आप का मूल्य बदल सकते आपके इस्तेमाल किए गए डेटा के अनुसार SqlDbType

+0

आमतौर पर सहायक होने पर यह तकनीकी रूप से प्रश्न का उत्तर नहीं है। इस प्रकार यह एक टिप्पणी होनी चाहिए। – Joey

+2

@ जॉय, हाँ आप सही हैं, आपके समय के लिए धन्यवाद। –

संबंधित मुद्दे

 संबंधित मुद्दे