AddWithValue पैरामीटर के पूर्ण होने पर अपवाद NULL है


89

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

अपवाद:

पैरामीटर की गई क्वेरी '(@application_ex_id nvarchar (4000)) SELECT E.application_ex_id A' पैरामीटर '@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 में लॉग इन सर्च.लॉग वैल्यू से NULL लेने में असमर्थ क्यों है (लेकिन DBNull को स्वीकार करने में सक्षम है)?

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

संदर्भ :

  1. SqlParameter को null असाइन करें
  2. डेटाटाइप लौटा तालिका में डेटा के आधार पर भिन्न होता है
  3. डेटाबेस स्माल्ट से C # nullable int में रूपांतरण त्रुटि
  4. 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 डेटाबेस के लिए एक शून्य मान भेजने का सही तरीका है।
— फिल गण

जवाबों:


148

कष्टप्रद, है ना।

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

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... वास्तव में अभी तक निश्चित नहीं है कि क्या यह एक अच्छा विचार है।


1
मैं Parametersसंपत्ति पर एक विस्तार सोच रहा था - क्या यह एक है Object?
— फिल गण

6
@Phil हममम, हाँ यह है, और मैं देख रहा हूँ तुम क्या मतलब है ... शायदAddWithValueAndTreatNullTheRightDamnedWay(...)
— मार्क Gravell

1
@MarcGravell क्या आप यह समझा सकते हैं कि यह कोड 1 में logSearch.LogID मूल्य (लेकिन DBNull को स्वीकार करने में सक्षम) से NULL लेने में असमर्थ क्यों है?
— LCJ

18
@ लिजो क्योंकि nullएक पैरामीटर मान का अर्थ है "इस पैरामीटर को न भेजें"। मुझे लगता है यह एक खराब निर्णय कि बस में पकाया गया था वास्तव में, मुझे लगता है। सबसे की DBNullएक मौलिक खराब निर्णय कि में पकाया गया था: stackoverflow.com/a/9632050/23354
— मार्क Gravell

1
@tylerH क्योंकि अशक्त कोल डाली नियमों की - जो सी # 9 में कमजोर किया जा सकता है
— मार्क Gravell

52

मुझे लगता है SqlParameterCollectionकि अशक्त मूल्यों को संभालने के लिए सिर्फ एक विस्तार विधि लिखना आसान है :

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);

मूल्य इंट या इंट हो सकता है ?, स्ट्रिंग, बूल या बूल ?, डेटटाइम या डेटटाइम? , आदि ?
— कीकेनेट

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

1
महान समाधान ... विस्तार विधियों को स्थिर वर्ग में परिभाषित किया जाना चाहिए। कैसे करें: एक कस्टम एक्सटेंशन विधि को लागू करें और कॉल करें
— क्रिस कैटिगनी

2
शायद मैं गलत हूँ (एक सी # नौसिखिया की तरह), लेकिन क्या आप इसे इस तरह से अधिक संक्षेप में नहीं कर सकते हैं:return collection.AddWithValue(parameterName, value ?? DBNull.Value);
— टोबीस फीट

1
@TobiasFeil हाँ, आप भी ऐसा कर सकते हैं। यह सिर्फ स्वाद की बात है।
— AxiomaticNexus

4

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

एसक्यूएल:

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

सी#:

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

0

कुछ समस्या, आवश्यक रूप से SQLDbType सेट के साथ

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

जहां SqlDbType.NVarChar आप टाइप करते हैं। आवश्यक रूप से SQL प्रकार सेट करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.