将null作为SQLParameter DateTime值传递

15

我有以下查询:

INSERT INTO CWS_FORWARDING_PROFILE
           (TNR_COMPANY_PROFILE,BOL_FORWARD_MAIL,BOL_FORWARD_SMS,BOL_FORWARD_MESSAGES
           ,DT_MO_FROM1,DT_MO_FROM2,DT_MO_FROM3,DT_MO_TO1,DT_MO_TO2,DT_MO_TO3
           ,DT_TU_FROM1,DT_TU_FROM2,DT_TU_FROM3,DT_TU_TO1,DT_TU_TO2,DT_TU_TO3
           ,DT_WE_FROM1,DT_WE_FROM2,DT_WE_FROM3,DT_WE_TO1,DT_WE_TO2,DT_WE_TO3
           ,DT_TH_FROM1,DT_TH_FROM2,DT_TH_FROM3,DT_TH_TO1,DT_TH_TO2,DT_TH_TO3
           ,DT_FR_FROM1,DT_FR_FROM2,DT_FR_FROM3,DT_FR_TO1,DT_FR_TO2,DT_FR_TO3
           ,DT_SA_FROM1,DT_SA_FROM2,DT_SA_FROM3,DT_SA_TO1,DT_SA_TO2,DT_SA_TO3
           ,DT_SU_FROM1,DT_SU_FROM2,DT_SU_FROM3,DT_SU_TO1,DT_SU_TO2,DT_SU_TO3)

            VALUES(@tnrProfile, @forwardMail, @forwardSms, @forwardMessages,
                    @MoFrom1, @MoFrom2, @MoFrom3, @MoTo1, @MoTo2, @MoTo3,
                    @TuFrom1, @TuFrom2, @TuFrom3, @TuTo1, @TuTo2, @TuTo3,
                    @WeFrom1, @WeFrom2, @WeFrom3, @WeTo1, @WeTo2, @WeTo3,
                    @ThFrom1, @ThFrom2, @ThFrom3, @ThTo1, @ThTo2, @ThTo3,
                    @FrFrom1, @FrFrom2, @FrFrom3, @FrTo1, @FrTo2, @FrTo3,
                    @SaFrom1, @SaFrom2, @SaFrom3, @SaTo1, @SaTo2, @SaTo3,
                    @SuFrom1, @SuFrom2, @SuFrom3, @SuTo1, @SuTo2, @SuTo3);

我将我的DateTime参数添加如下:

SqlParameter moFrom1Param = new SqlParameter("@MoFrom1", dTOForwarding.MoFrom1);
            moFrom1Param.IsNullable = true;
            moFrom1Param.Direction = ParameterDirection.Input;
            moFrom1Param.SqlDbType = SqlDbType.DateTime;
            cmd.Parameters.Add(moFrom1Param);

当我执行此操作时,只向某些参数提供实际日期时间,而其余所有内容都为空。因此,明确地说,从星期一到星期三的所有参数都具有日期时间值。 剩下的星期四到星期日没有。 所以它们传递为null。 我会收到以下错误:

The parameterized query '(@tnrProfile int,@forwardMail bit,@forwardSms bit,@forwardMessag' expects the parameter '@ThFrom1', which was not supplied.

我在stackoverflow和Google上搜寻了一些答案,但我找到的答案从未对我奏效。

所以我的问题是,如何确保如果我的DateTime参数的值为空,那么它会被SQL理解并作为null传递,而不是告诉我该参数未提供。

希望这里有人能帮助我。

谢谢。

编辑:这就是解决方案:

SqlParameter moFrom1Param = new SqlParameter("@MoFrom1", dTOForwarding.MoFrom1 == null ?
                (Object)DBNull.Value : dTOForwarding.MoFrom1);
            moFrom1Param.IsNullable = true;
            moFrom1Param.Direction = ParameterDirection.Input;
            moFrom1Param.SqlDbType = SqlDbType.DateTime;
            cmd.Parameters.Add(moFrom1Param);

3
你考虑过将数据规范化,这样你只需要储存实际存在的起点/终点对,并且可以处理超过3个点吗? - Damien_The_Unbeliever
5个回答

16
SqlParameter moFrom1Param = new SqlParameter("@MoFrom1", dTOForwarding.MoFrom1 == null ? DBNull.Value : dTOForwarding.MoFrom1);
            moFrom1Param.IsNullable = true;
            moFrom1Param.Direction = ParameterDirection.Input;
            moFrom1Param.SqlDbType = SqlDbType.DateTime;
            cmd.Parameters.Add(moFrom1Param);

当我尝试这个时,我得到了以下错误:"由于'System.DBNull'和'System.Data.SqlClient.SqlParameter'之间没有隐式转换,因此无法确定条件表达式的类型。" - JeremyVm
1
谢谢!这帮助我得到了正确的答案 :) 只需要在 DBNull.Value 中添加一个转换就可以让它工作了。 - JeremyVm
很惊讶需要一个转换,但无论如何很高兴你解决了它 :) - iDevForFun
6
谢谢Jeremy。我需要(object)DBNull.Value - Ian

10

你尝试过使用DBNull.Value吗?

SqlParameter moFrom1Param;
if (dTOForwarding.MoFrom1 != null)
    moFrom1Param = new SqlParameter("@MoFrom1", dTOForwarding.MoFrom1);  
else
    moFrom1Param = new SqlParameter("@MoFrom1", DBNull.Value);  

此外,您的代码显示“@MoFrom1”,但错误与“@ThFrom1”有关。

Guillaume,我刚试了一下,它无法编译。"运算符 '??' 不能应用于类型为 SqlParameter 和 DBNull 的操作数"。 - JeremyVm
Guillaume,我传递了所有参数。我只是展示了如何添加一个参数。我对其余的参数也是这样做的。总共有47个参数,其中42个是DateTime。 - JeremyVm
编辑了我的答案,移除了 ?? 运算符并在正确的值上执行逻辑。 - Guillaume
这个解决方案适用于可空的 DateTime,而其他解决方案不起作用。 - Christian Davén

3

使用 空合并运算符 ??DBNull.Value 结合使用:

SqlParameter moFrom1Param;

moFrom1Param = new SqlParameter( "@MoFrom1", dTOForwarding.MoFrom1 ?? DBNull.Value );  

1

看起来你没有赋予 null 值,类似这样:

var thFrom1Param = new SqlParameter("@ThFrom1", SqlDbType.SqlDateTime);
thFrom1Param.Value = DBNull.Value;
thFrom1Param.Direction = ParameterDirection.Input;

0

修改存储过程是可行的,但我认为有点不够严谨。

你可以在代码中处理它,以下方法适用于我:

        DateTime? myDate;

    if (TextBoxWithDate.Text != "")
    {
        myDate = DateTime.Parse(TextBoxWithDate.Text);
    }
    else
    {
        myDate = null;
    }

将myDate声明为DateTime类型,但可为空。如果文本框中的值为空,则将myDate设置为null并传递给存储过程。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接