2012-11-19 30 views
55

मेरे पास SQL ​​क्वेरी के लिए पैरामीटर निर्दिष्ट करने के लिए निम्न कोड है। जब मैं Code 1 का उपयोग करता हूं तो मुझे निम्नलिखित अपवाद मिल रहा है; लेकिन जब मैं Code 2 का उपयोग करता हूं तो ठीक काम करता है। Code 2 में हमारे पास शून्य के लिए एक चेक है और इसलिए if..else ब्लॉक है।अपवाद जब AddWithValue पैरामीटर NULL

अपवाद:

पैरामिट्रीकृत क्वेरी '(@application_ex_id nvarchar (4000)) का चयन E.application_ex_id ए' पैरामीटर '@application_ex_id' है, जो आपूर्ति नहीं कर रहा था की उम्मीद है।

कोड 1:

command.Parameters.AddWithValue("@application_ex_id", logSearch.LogID); 

कोड 2:

if (logSearch.LogID != null) 
{ 
     command.Parameters.AddWithValue("@application_ex_id", logSearch.LogID); 
} 
else 
{ 
     command.Parameters.AddWithValue("@application_ex_id", DBNull.Value); 
} 

प्रश्न

  1. क्या आप कृपया बता सकते हैं कि यह कोड 1 में लॉगऑर्च.लोगिड मान से न्यूल क्यों नहीं ले पा रहा है (लेकिन डीबीएनयूएल को स्वीकार करने में सक्षम)?

  2. क्या इसे संभालने के लिए कोई बेहतर कोड है?

संदर्भ:

  1. Assign null to a SqlParameter
  2. Datatype returned varies based on data in table
  3. Conversion error from database smallint into C# nullable int
  4. What is the point of DBNull?

कोड

public Collection<Log> GetLogs(LogSearch logSearch) 
    { 
     Collection<Log> logs = new Collection<Log>(); 

     using (SqlConnection connection = new SqlConnection(connectionString)) 
     { 
      connection.Open(); 

      string commandText = @"SELECT * 
       FROM Application_Ex E 
       WHERE (E.application_ex_id = @application_ex_id OR @application_ex_id IS NULL)"; 

      using (SqlCommand command = new SqlCommand(commandText, connection)) 
      { 
       command.CommandType = System.Data.CommandType.Text; 

       //Parameter value setting 
       //command.Parameters.AddWithValue("@application_ex_id", logSearch.LogID); 
       if (logSearch.LogID != null) 
       { 
        command.Parameters.AddWithValue("@application_ex_id", logSearch.LogID); 
       } 
       else 
       { 
        command.Parameters.AddWithValue("@application_ex_id", DBNull.Value); 
       } 

       using (SqlDataReader reader = command.ExecuteReader()) 
       { 
        if (reader.HasRows) 
        { 
         Collection<Object> entityList = new Collection<Object>(); 
         entityList.Add(new Log()); 

         ArrayList records = EntityDataMappingHelper.SelectRecords(entityList, reader); 

         for (int i = 0; i < records.Count; i++) 
         { 
          Log log = new Log(); 
          Dictionary<string, object> currentRecord = (Dictionary<string, object>)records[i]; 
          EntityDataMappingHelper.FillEntityFromRecord(log, currentRecord); 
          logs.Add(log); 
         } 
        } 

        //reader.Close(); 
       } 
      } 
     } 

     return logs; 
    } 
+3

उपयोग करने के लिए आप से क्या मतलब है आसान है बेहतर है? कोड 2 डेटाबेस में शून्य मान भेजने का सही तरीका है। –

+0

संदर्भ: http://stackoverflow.com/questions/13265704/conversion-error-from-database-smallint-into-c-sharp-nullable-int – Lijo

उत्तर

84

परेशान, है ना।

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

command.Parameters.AddWithValue("@application_ex_id", 
     ((object)logSearch.LogID) ?? DBNull.Value); 

या वैकल्पिक रूप से, "व्यवसायिक" की तरह एक उपकरण है, जो सभी कि आप के लिए खिलवाड़ करना होगा का उपयोग करें।

उदाहरण के लिए:

var data = conn.Query<SomeType>(commandText, 
     new { application_ex_id = logSearch.LogID }).ToList(); 

मैं परीक्षाIDataReader ... अभी तक है कि क्या यह एक अच्छा विचार है वास्तव में यकीन नहीं पाने के लिए व्यवसायिक के लिए एक विधि को जोड़ने के लिए कर रहा हूँ।

+0

@ फिल वास्तव में; ज्यादातर चीजें ... लेकिन मुझे 'ऑब्जेक्ट' पर एक्सटेंशन विधियों को जोड़ना पसंद नहीं है, और हम नहीं देख सकते हैं कि यह 'शून्य' 'बनाम 'स्ट्रिंग', आदि है ... लेकिन हाँ: इसे आसानी से किया जा सकता है पर्याप्त। –

+1

मैं 'पैरामीटर' संपत्ति पर एक विस्तार सोच रहा था - क्या यह एक 'ऑब्जेक्ट' है? –

+3

@ फिल हम्म, हां यह है, और मैं देखता हूं कि आपका क्या मतलब है ... शायद 'AddWithValueAndTreatNullTheRightDamnedWay (...) ' –

1

कुछ समस्या है, जरूरी SQLDbType

command.Parameters.Add("@Name", SqlDbType.NVarChar); 
command.Parameters.Value=DBNull.Value 

जहां SqlDbType.NVarChar आप टाइप सेट के साथ अनुमति दी। आवश्यक रूप से एसक्यूएल प्रकार सेट करें।

public static SqlParameter AddWithNullableValue(
    this SqlParameterCollection collection, 
    string parameterName, 
    object value) 
{ 
    if(value == null) 
     return collection.AddWithValue(parameterName, DBNull.Value); 
    else 
     return collection.AddWithValue(parameterName, value); 
} 

तो फिर तुम सिर्फ इसे कहते चाहते:

sqlCommand.Parameters.AddWithNullableValue(key, value); 
34

मैं यह आसान सिर्फ SqlParameterCollection कि शून्य मान संभालती के लिए एक विस्तार विधि लिखने के लिए लगता है संग्रहीत प्रक्रिया को कॉल करते समय यह कर रहे हैं: मुझे लगता है कि यदि आप पैरामीटर पर डिफ़ॉल्ट मान घोषित करते हैं और इसे आवश्यक होने पर ही जोड़ना आसान है।

उदाहरण के लिए: (एसक्यूएल)

DECLARE PROCEDURE myprocedure 
    @myparameter [int] = NULL 
AS BEGIN 

(C#)

int? myvalue = initMyValue(); 
if (myvalue.hasValue) cmd.Parameters.AddWithValue("myparamater", myvalue); 

मैं जानता हूँ कि यह पुराना है, लेकिन मैं इस उपयोगी पाते और साझा करना चाहते थे।

+0

_value_ ** int या int हो सकता है ?, स्ट्रिंग, बूल या बूल ?, डेटटाइम या डेटाटाइम? **, आदि? – Kiquenet

+0

@Kiquenet हाँ ... – AxiomaticNexus

+2

मैंने मार्क के जवाब को पढ़ा और सोचा "मुझे लगता है कि मैं पैरामीटर संग्रह के लिए सिर्फ एक विस्तार विधि लिखूंगा", फिर मैंने एक बाल नीचे स्क्रॉल किया ... (एक विस्तार विधि के बारे में अच्छी बात यह है कि मैं एक ही खोज/प्रतिस्थापन कर सकता हूं और मेरे सभी कोड अपडेट किए गए हैं) – jleach

-3

इस तरह एक स्थिर कक्षा बनाएं:

public static class Extensions 
{ 
    public static string RemoveNulls(this string container) 
    { 
     if (container == null) 
      container = ""; 
     return container; 
    } 
} 
फिर अपने कोड में

, ऐसा करते हैं:

Parameters.AddWithValue(sName, Value.RemoveNulls()); 

यह बुलेट प्रूफ और बहुत

+1

यह "" डालेगा और शून्य नहीं होगा ... – Lars

+0

यही वह चाहता है - एक नल दर्ज न करें – TheWizardOfTN