2009-10-09 17 views
10

मैं एक संग्रहित प्रो कॉल करने के लिए एक सी # दिनचर्या लिख ​​रहा हूं। पैरामीटर सूची में मैं गुजर रहा हूं, यह संभव है कि मूल्यों में से एक कानूनी रूप से शून्य हो। तो मैंने सोचा कि मैं इस तरह की एक पंक्ति का उपयोग करेंगे:क्या सी # में स्ट्रिंग और डीबीएनएल को जोड़ना संभव है?

cmd.Parameters.Add(new SqlParameter("@theParam", theParam ?? DBNull.Value)); 

दुर्भाग्य से, यह निम्नलिखित त्रुटि देता है:

CS0019: Operator '??' cannot be applied to operands of type 'string' and 'System.DBNull'

अब, यह काफी स्पष्ट लगता है, लेकिन मैं तर्क के पीछे समझ में नहीं आता यह। यह क्यों काम नहीं करेगा? (और अक्सर, जब मैं क्यों कुछ काम नहीं कर रहा समझ में नहीं आता, ऐसा नहीं है कि यह नहीं कर सकते हैं काम ... यह है कि मैं गलत कर रहा हूँ। है)

मैं वास्तव में फैलाने के लिए है यह लंबे समय में अगर कथन में बाहर हो गया?

संपादित करें:।। (एक अलग रूप में, बस का उपयोग करने के "शून्य" के रूप में, यह काम नहीं करता सुझाव उन लोगों के लिए के रूप में मैं मूल रूप से सोचा अशक्त DBNull में भी स्वतः अनुवादित होगा, लेकिन यह जाहिरा तौर पर नहीं करता है (कौन जानता था?))

उत्तर

16

ऐसा नहीं, नहीं। प्रकारों से मेल खाना है। टर्नरी के लिए भी यही सच है।

अब, "मैच" द्वारा, मेरा मतलब यह नहीं है कि उन्हें वही होना चाहिए। लेकिन उन्हें असाइनमेंट को संगत होना है। असल में: एक ही विरासत पेड़ में।

एक तरीका यह चारों ओर पाने के लिए अपने स्ट्रिंग डाली पर आपत्ति करने के लिए है:

var result = (object)stringVar ?? DBNull.Value; 

लेकिन क्योंकि यह मतलब है कि आप SqlParameter निर्माता के बारे में अधिक अपने प्रकार के अधिकार प्राप्त करने के लिए भरोसा कर रहे हैं मुझे यह पसंद नहीं है, । इसके बजाय, मैं इस तरह यह करना पसंद:

cmd.Parameters.Add("@theParam", SqlDbTypes.VarChar, 50).Value = theParam; 
// ... assign other parameters as well, don't worry about nulls yet 

// all parameters assigned: check for any nulls 
foreach (var p in cmd.Parameters) 
{ 
    if (p.Value == null) p.Value = DBNull.Value; 
} 

भी ध्यान रखें कि मैं स्पष्ट रूप से पैरामीटर प्रकार की घोषणा की।

+0

जानकारी के लिए, कमांड एक CommandBuilder द्वारा बनाई गई एक सेट है आपके लिए बनाए गए पैरामीटर का। हालांकि, एक ही समस्या उत्पन्न होती है कि आप जेनरेटेड पैरामीटर चयन में पैरामीटर में से किसी एक को नल पास करने की उम्मीद नहीं कर सकते हैं। आपको अभी भी ऊपर वर्णित अनुसार करना है। – rohancragg

+0

अच्छा सरल समाधान :-) – IrishChieftain

+0

आप इसे करने के लिए एक एक्सटेंशन विधि भी बना सकते हैं। –

0

मुझे पूरा यकीन है कि एसकल्प पैरामीटर कन्स्ट्रक्टर के परिणामों को सिर्फ एक डीबीएनयूएल के रूप में भेजा जा रहा है। वैल्यू ... मुझे गलत हो सकता है, क्योंकि मैं डीबी एक्सेस के लिए एंटरप्राइज़ लाइब्रेरी का उपयोग करता हूं, लेकिन मुझे पूरा यकीन है कि एक नल भेजना ठीक है।

+2

हाँ, तुम गलत हो रहा है -1। नल पास करने की कोशिश करने के परिणामस्वरूप SQL सर्वर "पैरामीटर ... मौजूद नहीं है" त्रुटि देगा। – erikkallen

+0

एरिक, मैंने होगा मान आप सही इस एक के रूप में मैं व्यवहार आप VB.NET में कई बार वर्णन देखा होगा पर हैं। इस तथ्य के अलावा कि यह सी # है, मुझे नहीं पता कि अन्य परिस्थितियां अलग-अलग हैं जो इसे मेरे लिए काम करने की अनुमति देती है, न कि एरिक्कलेन या बेस्का। –

+0

आह, मैं आमतौर पर SqlHelper वर्ग का उपयोग करें और मैं सिर्फ इस लाइन के अंदर पाया: हैं (p.Direction = ParameterDirection.InputOutput OrElse p.Direction = ParameterDirection.Input) andalso p.Value कुछ भी नहीं है तो फिर p.Value = DBNull .Value अंत तो ... यही कारण है कि यह काम करता है। –

-1

सुनिश्चित नहीं है कि आपके प्रश्न का विशिष्ट उत्तर है, लेकिन इसके बारे में कैसे?

string.IsNullOrEmpty(theParam) ? DBNull.Value : theParam 

या खाली है, तो ठीक

(theParam == null) ? DBNull.Value : theParam 
+1

नोप-टर्नरी को भी मिलान करने की आवश्यकता होती है। –

+0

डी ओह! वह मुझे पहले से परीक्षण के लिए सिखाएगा! – n8wrl

5
new SqlParameter("@theParam", (object)theParam ?? DBNull.Value) 
+0

आपको दोनों को शून्य में डालने की भी आवश्यकता नहीं है। मैं आमतौर पर नई SqlParameter ("@ theParam", (वस्तु) theParam ?? DBNull.Value) – erikkallen

3

है ?? यदि ऑपरेटर शून्य नहीं है, तो ऑपरेटर बाएं हाथ के ऑपरेंड को वापस लौटाता है, अन्यथा यह सही ऑपरेंड देता है। लेकिन आपके मामले में वे अलग-अलग प्रकार हैं, इसलिए यह काम नहीं करता है।

+0

(अप्रासंगिक संपादन किया इतना है कि यह मुझे इस जवाब को वोट देना होगा।) कर – Beska

0

सेमीडी। पैरामीटर। जोड़ें (नया एसक्यूएल पैरामीटर ("@ द पैराम", (पैराम == नल)? डीबीएनयूएल। वैल्यू: पैराम));

2

कारण आप नल कोलेसे ऑपरेटर का उपयोग नहीं कर सकते हैं यह है कि इसे एक प्रकार का रिटर्न देना है और आप एक से अधिक प्रकार के प्रदान कर रहे हैं। theParam एक स्ट्रिंग है। DbNull.ValueSystem.DbNull प्रकार के एक स्थिर उदाहरण का संदर्भ है। यही वह क्रियान्वयन जैसा दिखता है;

public static readonly DBNull Value = new DBNull(); 
//the instantiation is actually in the 
//static constructor but that isn't important for this example 

तो अगर आप एक NullCoalesce विधि के लिए गए थे, क्या अपनी वापसी प्रकार हो सकता है? यह System.String और System.DbNull दोनों नहीं हो सकता है, यह एक या दूसरे, या एक सामान्य मूल प्रकार होना चाहिए।

तो इस प्रकार के कोड की ओर जाता है;

cmd.Parameters.Add(
    new SqlParameter("@theParam", (object)theParam ?? (object)DBNull.Value) 
); 
2

अशक्त संगठित होना केवल एक ही प्रकार के डेटा के साथ साथ ऑपरेटर। आप एसक्यूएल पैरामीटर को न्यूल भेज नहीं सकते क्योंकि यह एसक्यूएल सर्वर कहता है कि आपने पैरामीटर निर्दिष्ट नहीं किया है।

आप

new SqlParameter("@theParam", (object)theParam ?? (object)DBNull.Value) 

उपयोग कर सकते हैं या आप की तरह

public static object GetDataValue(object o) 
{ 
    if (o == null || String.Empty.Equals(o)) 
     return DBNull.Value; 
    else 
     return o; 
} 

, एक समारोह है कि DBNull लौट जब अशक्त पाया जाता है बना सकते हैं और फिर इस वाक्य

new SqlParameter("@theParam", GetDataValue(theParam)) 
+4

हाँ, GetDataValue विधि यह है कि मैंने इसे अतीत में कैसे संभाला है। मैं वास्तव में चाहता हूं कि इसके लिए एक अंतर्निहित व्यवहार था। ऐसी संपत्ति की तरह आप ADO.NET कक्षाओं पर निर्दिष्ट कर सकते हैं, जो डीबीएनयूएलएल.वैल्यू (या जो कुछ आप निर्दिष्ट करते हैं) को प्रतिस्थापित करते हैं, जब यह शून्य मान प्राप्त होता है। – LoveMeSomeCode

+0

हाँ, मैं भी मैं शून्य निर्दिष्ट करने में सक्षम होना चाहता हूं और इसे स्वचालित रूप से डीबीएनएल में मानचित्रित करने देता हूं। –

+0

@LoveMe: इसके लिए मुझे गिनें डिफ़ॉल्ट रूप से संभाला जाना चाहिए! –

0

उपयोग फोन:

(वस्तु के रूप में पैराम) ?? (DBNull.Value वस्तु के रूप में)

इस मामले में ऑपरेटर के दोनों भागों ?? एक ही प्रकार के हैं।

+0

1) आपको केवल एक तरफ डालना होगा, दोनों ओवरकिल हैं; 2) जब तक आप कास्ट के वापसी मूल्य (यानी टाइपविच के रूप में) की जांच करने के लिए आगे बढ़ते हैं, तब तक 'as' का उपयोग करना एक बुरा विचार है - एक सामान्य कास्ट स्पष्ट मंशा को संचारित करता है। –

1

अपने संग्रहीत proc में जब आप आने चर घोषित, यह शून्य पर वर बराबर सेट करें और फिर अपने कोई तिथि नहीं कोड से में इसे पारित नहीं है, यह तो एसक्यूएल

@theParam as varchar(50) = null 
से डिफ़ॉल्ट मान लेने जाएगा

और फिर अपने कोई तिथि नहीं

if (theParam != null) 
    cmd.Parameters.Add(new SqlParameter("@theParam", theParam)); 

में यह, कैसे मैं आमतौर पर मेरी संग्रहीत procs के लिए विकल्प और/या डिफॉल्ट मान पास

+0

मुझे लगता है कि आपका मतलब है "! =", आपने नमूना तय किया है। –

+0

हाँ, धन्यवाद। मैंने इसे देखा, जबकि मैं कोड ब्लॉक को काम करने की कोशिश कर रहा था और वापस जाने और संपादित करने के लिए भूल गया था। –

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