একটি স্কেলপ্যারামিটারে নাল বরাদ্দ করুন


188

নিম্নলিখিত কোডটি একটি ত্রুটি দেয় - "DBnull থেকে কোনও সংকেত রূপান্তর নেই" "

SqlParameter[] parameters = new SqlParameter[1];    
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex;
parameters[0] = planIndexParameter;

4
আপনি AgeItem.AgeIndex কাস্ট করার জন্য আপত্তি জানাতে আমি মনে করি ... প্রয়োজন stackoverflow.com/questions/202271/... (BTW কেন ==? 3 য় লাইনের শেষে)
গ্রেগ

উত্তর:


341

সমস্যাটি হ'ল ?:অপারেটর intরিটার্নের ধরণটি নির্ধারণ করতে পারে না কারণ আপনি হয় কোনও মান বা একটি ডিবিএনল টাইপ মান প্রদান করছেন যা উপযুক্ত নয়।

আপনি অবশ্যই এজেন্ডেক্সের উদাহরণটি টাইপ করতে পারেন objectযা ?:প্রয়োজনীয়তা পূরণ করবে ।

আপনি নীচের মতো ??নাল-কোলেসিং অপারেটরটি ব্যবহার করতে পারেন

SqlParameter[] parameters = new SqlParameter[1];     
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = (object)AgeItem.AgeIndex ?? DBNull.Value;
parameters[0] = planIndexParameter; 

অপারেটরটির জন্য এমএসডিএন ডকুমেন্টেশনের একটি উদ্ধৃতি এখানে ?:সমস্যাটি ব্যাখ্যা করে explains

হয় প্রথম_প্রকাশ এবং দ্বিতীয়_প্রকাশের ধরণ একই রকম হতে হবে, বা এক প্রকার থেকে অন্য প্রকারের মধ্যে অন্তর্নিহিত রূপান্তর থাকতে হবে।


কেন আপত্তি নাল নিক্ষেপ করার চেষ্টা করা হয় সেখানে ব্যতিক্রম হয় না? আমি মনে করি এটি হওয়া উচিতAgeItem.AgeIndex as object
নীলস ব্রিনচ

@ নীলস ব্রিঞ্চ, কোনও ব্যতিক্রম হবে না কারণ নাল একটি বস্তু এবং যতক্ষণ আপনি এটিকে অবলম্বন করার চেষ্টা করবেন না এটি পুরোপুরি আইনী। যাইহোক, এই উদাহরণে এটি আপত্তি করার জন্য নিক্ষেপ করা বাতিল নয়, এটি DBNull.Value যা আসলে একটি মান ধরণের। দ্য ?? অপারেটর বলেছে যে 'যদি আজিটেমটেম.এজআইএনডেক্স নাল থাকে তবে ডিবিএনলকে ফেরান al মূল্য অন্যথায় অ্যাজ আইটেম.এজআইএনডেক্স পুনরুদ্ধার করুন' তারপরে প্রতিক্রিয়াটি আপত্তিতে ফেলে দেওয়া হয়। আরও তথ্যের জন্য নাল কোলেসিং অপারেটরটি দেখুন। msdn.microsoft.com/en-us/library/ms173224.aspx
ক্রিস টেলর

3
টেকনিক্যালি, নাল-কোয়ালেসিং অপারেটর ব্যবহার করে আপনার সমাধান ??আপনি নিয়মিত তিন ব্যবহার করতে হলে একই সমাধান ?:- আপনি এখনও নিক্ষেপ করার প্রয়োজন AgeItem.AgeIndexএকটা অবজেক্ট: planIndexParameter.Value = AgeItem.AgeIndex.HasValue ? (object)AgeItem.AgeIndex : DBNull.Value;
ফার্নিচার

আপনি যদি ?:কোনও টাইপ-নির্দিষ্ট তুলনা করতে নিয়মিত ত্রিভুজ ব্যবহার করেন তবে পুরো এক্সপ্রেশনটি ingালাই কাজ করবে না। : আপনি তাই ভালো অ dbnull প্যারামিটার নিক্ষেপ করে থাকsomeID == 0 ? DBNull.Value : (object)someID
ingredient_15939

এটি সত্য তবে আপনার যদি নাল-সক্ষম মানটি ফাংশনের একটি প্রবেশ প্যারামিটার হিসাবে ব্যবহার করতে চান যা ফলাফলটি SQLParameter গ্রহণ করে এবং যদি এটি নাল হয় তবে আপনার ত্রুটি হয়েছে এইভাবে কাজ করা হয় না এবং আপনার যদি সহজ-অন্যভাবে ব্যবহার করা উচিত। উদাহরণস্বরূপ: নমুনা। পাঠ্য। ট্রিম ()! = ""? ফানক (নমুনা। পাঠ্য): ডিবি নল.ভ্যালু; হিসাবে কাজ করবে না?: এবং ??
কিউমাস্টার

102

গৃহীত উত্তরটি একটি কাস্ট ব্যবহারের পরামর্শ দেয়। তবে বেশিরভাগ এসকিউএল টাইপের একটি বিশেষ নাল ক্ষেত্র রয়েছে যা এই castালাই এড়াতে ব্যবহার করা যেতে পারে।

উদাহরণস্বরূপ, SqlInt32.Null"এমন একটি ডিবিএনল প্রতিনিধিত্ব করে যা SQLlnt32 শ্রেণীর এই উদাহরণকে অর্পণ করা যেতে পারে" "

int? example = null;
object exampleCast = (object) example ?? DBNull.Value;
object exampleNoCast = example ?? SqlInt32.Null;

2
পরামর্শটি আশাব্যঞ্জক বলে মনে হয়েছিল তাই আমি "System.Data.SqlTypees.SQLlString.Null" চেষ্টা করেছি কিন্তু এটি কার্যকর হয়নি। এটি সত্য (নাল) দিয়ে ফাঁকা রেখে পরিবর্তে "নুল" ('এন', 'ইউ', 'ল', 'ল') ক্ষেত্রের মধ্যে রাখে। তবে, পুরানো 2010 "গৃহীত উত্তর" যা (অবজেক্ট) দিয়ে castালাই ব্যবহার করে ?? DBNull.Value সঠিকভাবে কাজ করে। (আমি যে ADO.NET সরবরাহকারীর ব্যবহার করেছি সেটি এসকিউএলাইট ছিল তবে আমি নিশ্চিত নই যে এটির কোনও পার্থক্য হয়েছে কিনা)) আমি পরামর্শ দিই যে অন্যরা নূন আচরণটি প্রত্যাশার মতো কাজ করছে কিনা তা নিশ্চিত করার জন্য ব্রায়ানের টিপটি সাবধানতার সাথে পরীক্ষা করে।
জেসদেভ

6
@ জাসডেভ: আমি একটি উচ্চ প্রতিনিধি ব্যবহারকারী (আমি মনে করি মার্ক গ্র্যাভেল) এর মন্তব্যে এই কৌশলটি বর্ণনা করা অস্পষ্টভাবে স্মরণ করছি এবং বলা হয়েছে যে এটি কেবল মাইক্রোসফ্ট এসকিউএল সার্ভারে কাজ করে।
ব্রায়ান

ব্রাউজ পয়েন্ট আউট হওয়ার সাথে সাথে এসকিউএল সার্ভারে জাসদেভ সরবরাহকারীর পার্থক্য হবে।
লঙ্কাইমার্ট

এই উত্তরটি কেবলমাত্র একটি স্পষ্টর cast নমুনা কোডে, exampleNoCastঅবজেক্ট হিসাবে ঘোষিত হয়, সুতরাং objectালাইয়ের জন্য বস্তুটি এখনও ঘটে। যদি, ওপি-র কোডের মতো, মানটি সরাসরি স্কেলপ্যারামিটারে অর্পণ করা হয় al ভ্যালু যা টাইপ অবজেক্টেরও হয়, আপনি এখনও কাস্ট পাবেন।
স্কট

31

আপনার DBNull.Valueএসকিউএলকম্যান্ডের মধ্যে নাল প্যারামিটার হিসাবে পাস হওয়া দরকার , যদি না সঞ্চিত পদ্ধতির মধ্যে কোনও ডিফল্ট মান নির্দিষ্ট না করা হয় (যদি আপনি সঞ্চিত পদ্ধতি ব্যবহার করছেন)। DBNull.Valueক্যোয়ারী এক্সিকিউশন হওয়ার আগে যে কোনও অনুপস্থিত প্যারামিটারের জন্য নিযুক্ত করা ভাল উপায় এবং নীচের ফোরচ কাজটি করবে।

foreach (SqlParameter parameter in sqlCmd.Parameters)
{
    if (parameter.Value == null)
    {
        parameter.Value = DBNull.Value;
    }
}

অন্যথায় এই লাইনটি পরিবর্তন করুন:

planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex;

নিম্নরূপ:

if (AgeItem.AgeIndex== null)
    planIndexParameter.Value = DBNull.Value;
else
    planIndexParameter.Value = AgeItem.AgeIndex;

কারণ আপনি শর্তাধীন বিবৃতিতে বিভিন্ন ধরণের মান ব্যবহার করতে পারবেন না, কারণ ডিবিএনল এবং ইনটি একে অপরের থেকে পৃথক। আশা করি এটি সাহায্য করবে।


এই উত্তরটি সত্যিই দুর্দান্ত কারণ এটি সম্ভাব্য প্রতিটি উপায়ে উদাহরণ দেয়। আমি প্রথম পদ্ধতির পছন্দ করি, আমি সাধারণত ইএফ ব্যবহার করি তবে এই প্রয়োজনে এটি করতে পারে না এবং এটি আমার অনেক সময় সাশ্রয় করে। ধন্যবাদ!
লিয়ান্দ্রো

23

কোডের একটি লাইন সহ, এটি চেষ্টা করুন:

var piParameter = new SqlParameter("@AgeIndex", AgeItem.AgeIndex ?? (object)DBNull.Value);

5

এটা চেষ্টা কর:

SqlParameter[] parameters = new SqlParameter[1];    
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);

planIndexParameter.IsNullable = true; // Add this line

planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex== ;
parameters[0] = planIndexParameter;

5

আপনি যদি শর্তসাপেক্ষে (টের্নারি) অপারেটর ব্যবহার করেন তবে সংকলকটির উভয় প্রকারের মধ্যেই অন্তর্নিহিত রূপান্তর প্রয়োজন, অন্যথায় আপনি একটি ব্যতিক্রম পান।

সুতরাং আপনি উভয়কে একটিতে কাস্ট করে এটি ঠিক করতে পারেন System.Object:

planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : (object) AgeItem.AgeIndex;

তবে যেহেতু ফলাফলটি সত্যই সুন্দর নয় এবং আপনাকে সর্বদা এই rememberালাই মনে রাখতে হবে, আপনি এর পরিবর্তে এই জাতীয় এক্সটেনশন পদ্ধতি ব্যবহার করতে পারেন:

public static object GetDBNullOrValue<T>(this T val)
{
    bool isDbNull = true;
    Type t = typeof(T);

    if (Nullable.GetUnderlyingType(t) != null)
        isDbNull = EqualityComparer<T>.Default.Equals(default(T), val);
    else if (t.IsValueType)
        isDbNull = false;
    else
        isDbNull = val == null;

    return isDbNull ? DBNull.Value : (object) val;
}

তারপরে আপনি এই সংক্ষিপ্ত কোডটি ব্যবহার করতে পারেন:

planIndexParameter.Value = AgeItem.AgeIndex.GetDBNullOrValue();

1

আমার মতে আরও ভাল উপায় হ'ল স্ক্লককমন্ড শ্রেণীর প্যারামিটার সম্পত্তি সহ এটি করা :

public static void AddCommandParameter(SqlCommand myCommand)
{
    myCommand.Parameters.AddWithValue(
        "@AgeIndex",
        (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex);
}

তবে মানটি যদি হয় তবে DBNull.ValueADO.NET এর মধ্যে কিছুটা কঠিন সময় অনুমান করতে পারে যে স্ক্যালডিবিটাইপ কী হতে পারে তা ........ এটি সুবিধাজনক - তবে কিছুটা বিপজ্জনক ....
marc_s

1

উপলব্ধ নুলাবল (টি) কাঠামো ব্যবহার বিবেচনা করুন। এটি কেবলমাত্র মানগুলি সেট করতে দিবে যদি আপনি সেগুলি রাখেন এবং আপনার এসকিউএল কমান্ড অবজেক্টগুলি আপনার শেষের কোনও ঝামেলা ছাড়াই ননযোগ্য মানটি এবং প্রক্রিয়াটিকে স্বীকৃতি দেবে।


1
if (_id_categoria_padre > 0)
{
    objComando.Parameters.Add("id_categoria_padre", SqlDbType.Int).Value = _id_categoria_padre;
}
else
{
    objComando.Parameters.Add("id_categoria_padre", DBNull.Value).Value = DBNull.Value;
}

0

এটা চেষ্টা কর:

if (AgeItem.AgeIndex != null)
{
   SqlParameter[] parameters = new SqlParameter[1];
   SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
   planIndexParameter.Value = AgeItem.AgeIndex;
   parameters[0] = planIndexParameter;
}

অন্য কথায়, যদি প্যারামিটারটি শূন্য থাকে তবে এটি কেবল আপনার সঞ্চিত প্রোকে প্রেরণ করবেন না (ধরে নিলে অবশ্যই যে সংরক্ষণাগারটি আপনার প্রশ্নে অন্তর্ভুক্ত নাল প্যারামিটার গ্রহণ করে)।


তবে এখন, আপনি কেবলমাত্র একটি প্যারামিটার বাদ দিচ্ছেন - আমি অত্যন্ত সন্দেহ করি যে সঞ্চিত পদ্ধতিটি এতে খুশি হবে .... সম্ভবত, কলটি "এজেন্টেক্সের পরামিতিগুলির কোনও মূল্য নেই যা সরবরাহ করা হয়েছিল" বলে উল্লেখ করা ব্যর্থ হবে .... .... ।
marc_s

কি দারুন. হর্ষ। প্যারামিটারটি পাস না করা হলে সঞ্চিত সংগ্রহটি কোনও মানকে ডিফল্টরূপে লিখুন (@ এজেন্ডেক্স ইনট = 0)। সব সময় ঘটে. ক্লায়েন্ট হয় হয় ডিফল্ট গ্রহণ করতে পারে, বা পরামিতি পেরিয়ে ওভাররাইড করতে পারেন। ডাউনটা কেন?
ফ্লিপস্টার

0

এরকম কিছু চেষ্টা করুন:

if (_id_categoria_padre > 0)
{
    objComando.Parameters.Add("id_categoria_padre", SqlDbType.Int).Value = _id_categoria_padre;
}
else
{
    objComando.Parameters.Add("id_categoria_padre", DBNull.Value).Value = DBNull.Value;
}


0
if (AgeItem.AgeIndex== null)  
    cmd.Parameters.Add(new SqlParameter("ParaMeterName", SqlDbType.DateTime).Value = DBNull);  
else  
    cmd.Parameters.Add(new SqlParameter("ParaMeterName", SqlDbType.DateTime).Value = AgeItem.AgeIndex);

0

আমি কেবল এটিই করি ...

        var PhoneParam = new SqlParameter("@Phone", DBNull.Value);
        if (user.User_Info_Phone != null)
        {
            PhoneParam.SqlValue = user.User_Info_Phone;
        }

        return this.Database.SqlQuery<CustLogonDM>("UpdateUserInfo @UserName, @NameLast, @NameMiddle, @NameFirst, @Address, @City, @State, @PostalCode, @Phone",
            UserNameParam, NameLastParam, NameMiddleParam, NameFirstParam, AddressParam, CityParam, StateParam, PostalParam, PhoneParam).Single();

0
            dynamic psd = DBNull.Value;

            if (schedule.pushScheduleDate > DateTime.MinValue)
            {
                psd = schedule.pushScheduleDate;
            }


            sql.DBController.RunGeneralStoredProcedureNonQuery("SchedulePush",
                     new string[] { "@PushScheduleDate"},
                     new object[] { psd }, 10, "PushCenter");

0

এর জন্য একটি সাধারণ এক্সটেনশন পদ্ধতিটি হ'ল:

    public static void AddParameter(this SqlCommand sqlCommand, string parameterName, 
        SqlDbType sqlDbType, object item)
    {
        sqlCommand.Parameters.Add(parameterName, sqlDbType).Value = item ?? DBNull.Value;
    }

0

আমি নাল চেক সহ একটি সহজ পদ্ধতি ব্যবহার করি।

    public SqlParameter GetNullableParameter(string parameterName, object value)
    {
        if (value != null)
        {
            return new SqlParameter(parameterName, value);
        }
        else
        {
            return new SqlParameter(parameterName, DBNull.Value);
        }
    }

1
শর্তসাপেক্ষ যুক্তি কি পিছনে? DBNull.Value প্রথমটি থাকা উচিত?
মার্ক স্কুলথিস

অবশ্যই। সংশোধন করা হয়েছে। ধন্যবাদ।
Zhi আন

0

আমার কোড, বাস্তব প্রকল্পে কাজ করে টার্নারি অপারেটরটি দেখুন বর্গফুট তৈরি করুন এটি আমার পক্ষে সেরা উপায়, সমস্যা সহ:

    public bool Key_AddExisting
    (
          string clave
        , int? idHito_FileServer
        , int? idTipoDocumental_Almacen
        , string tipoExp_CHJ
        , int idTipoExp_Verti2
        , int idMov_Verti2
    )
    {
        List<SqlParameter> pars = new List<SqlParameter>()
        {
              new SqlParameter { ParameterName = "@Clave", Value = clave }
    LOOK -> , idHito_FileServer == null ? new SqlParameter { ParameterName = "@IdHito_FileServer", Value = DBNull.Value } : new SqlParameter { ParameterName = "@IdHito_FileServer", Value = idHito_FileServer }
    LOOK -> , idTipoDocumental_Almacen == null ? new SqlParameter { ParameterName = "@IdTipoDocumental_Almacen", Value = DBNull.Value } : new SqlParameter { ParameterName = "@IdTipoDocumental_Almacen", Value = idTipoDocumental_Almacen }
            , new SqlParameter { ParameterName = "@TipoExp_CHJ", Value = tipoExp_CHJ }
            , new SqlParameter { ParameterName = "@IdTipoExp_Verti2", Value = idTipoExp_Verti2 }
            , new SqlParameter { ParameterName = "@IdMov_Verti2", Value = idMov_Verti2 }
        };

        string sql = "INSERT INTO [dbo].[Enlaces_ClavesCHJ_MovimientosVerti2] " +
            "( " +
            "  [Clave] " +
            ", [IdHito_FileServer] " +
            ", [IdTipoDocumental_Almacen] " +
            ", [TipoExp_CHJ] " +
            ", [IdTipoExp_Verti2] " +
            ", [IdMov_Verti2] " +
            ") " +
            "VALUES" +
            "( " +
            "  @Clave" +
            ", @IdHito_FileServer" +
            ", @IdTipoDocumental_Almacen" +
            ", @TipoExp_CHJ" +
            ", @IdTipoExp_Verti2" +
            ", @IdMov_Verti2" +
            ")";

        return DbBasic.ExecNonQuery(ref this.conn, sql, pars);
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.