C# ASP.Net中Parameters.AddWithValue方法拒绝参数的空值。

7

我正在使用存储过程填充表格。该表格允许姓名的中间名为空,但是我收到了以下错误信息:

存储过程或函数'uspInsertPersonalAccountApplication'期望提供参数'@MiddleInitial',但未提供。

谢谢!

   public void ProcessForm(string[] InputData)
    {
        string ConnString = System.Configuration.ConfigurationManager.ConnectionStrings["AssociatedBankConnectionString"].ToString();

        SqlConnection conn = new SqlConnection(ConnString);
        SqlCommand cmd = new SqlCommand("uspInsertPersonalAccountApplication", conn);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("@AccountType", "Savings");
        cmd.Parameters.AddWithValue("@AccountSubType", "Savings");
        cmd.Parameters.AddWithValue("@ExistingCustomer","No");
        conn.Open();
        cmd.ExecuteNonQuery();

        conn.Close();
    }
7个回答

5
您可以将以下扩展方法添加到项目并使用:

您可以将以下扩展方法添加到项目并使用:

public static SqlParameter AddWithValueSafe(this SqlParameterCollection parameters, string parameterName, object value)
{
    return parameters.AddWithValue(parameterName, value ?? DBNull.Value);
}

4

这里有两种选择:

修改您的存储过程,使@MiddleInitial参数变为可选(目前不可选,因此会抛出错误)

@MiddleInitial nvarchar(10) = NULL

或者将以下行添加到您的代码中:

cmd.Parameters.AddWithValue("@MiddleInitial", null);

1
我正在传递53个参数,其中许多可以为null。如何在不用IF语句包装每个赋值的情况下动态设置DBNull.Value? - Susan
1
如果可以修改存储过程,则修改可能为空的参数,并在存储过程声明中将它们设置为可选。这是最灵活的解决方案。如果不可能,您可以使用 SqlCommandBuilder.DeriveParameters(command); 并在循环中为每个参数设置 DBNull.Value。然后再分配您想要的参数。 - Marcin
3
请参考https://dev59.com/h2HVa4cB1Zd3GeqPjAwp#9518215的评论:使用`cmd.Parameters.AddWithValue("@MiddleInitial", (object)yourVal ?? DBNull.Value);或添加一个类似于AddParamWithValueOrNull()`的扩展方法。 - Rory
2
我尝试了AddWithValue("@param", null);但没有成功。在存储过程中设置默认值(即@param datetime = null)解决了问题。 - Kevin Won

3

尝试传递 DBNull.Value 而不是 null


我正在传递53个参数,其中许多可以为null。如何在不用IF语句包装每个赋值的情况下动态设置DBNull.Value? - Susan
1
在值后面添加 ?? DBNull.Value,或者创建一个名为 AddValueWithNonNullParameter 的函数来自动添加。 - Andomar
这样?Intellisense 给了我一个错误,而且 Intellisense 无法识别 AddValueWithNullParameter ------- cmd.Parameters.AddWithValue("@MiddleInitial", InputData[11] ?? DBNull.Value); - Susan
жҳҜзҡ„пјҢ?? зҡ„дҫӢеӯҗеә”иҜҘеҸҜд»Ҙе·ҘдҪңгҖӮеҰӮжһң ?? еүҚйқўзҡ„еҖјдёә nullпјҢеҲҷиҝ”еӣһ ?? еҗҺйқўзҡ„еҖјгҖӮеҮҪж•° AddValueWithNonNullParameter дёҚеӯҳеңЁпјҢжӮЁйңҖиҰҒиҮӘе·ұе®һзҺ° :) - Andomar
Intellisense提示:运算符“??”不能用于类型为“string”和“System.DBNull”的操作数。 - Susan
1
尝试使用 ((object) InputData[11]) ?? DBNull.Value - Andomar

1

你需要对所有东西进行声明 - 即使它是null。

对于MiddleInitial,请使用DBNull.Value

cmd.Parameters.AddWithValue("@MiddleInitial",DBNull.Value);

1

我创建了一个扩展方法来解决这个问题。如果你可以更新存储过程,Marcin的建议也值得考虑。

cmd.Parameters.AddString("@MyParamName", myValue);


public static class SQLExtension
{
    public static void AddString(this SqlParameterCollection collection, string parameterName, string value)
    {
        collection.AddWithValue(parameterName, ((object)value) ?? DBNull.Value);
    }
}

0

添加MiddleInitial参数,允许空值

public void ProcessForm(string[] InputData)
    {
        string ConnString = System.Configuration.ConfigurationManager.ConnectionStrings["AssociatedBankConnectionString"].ToString();

        SqlConnection conn = new SqlConnection(ConnString);
        SqlCommand cmd = new SqlCommand("uspInsertPersonalAccountApplication", conn);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("@AccountType", "Savings");
        cmd.Parameters.AddWithValue("@AccountSubType", "Savings");
        cmd.Parameters.AddWithValue("@ExistingCustomer","No");
        cmd.Parameters.AddWithValue("@MiddleInitial",DBNull.Value);
        conn.Open();
        cmd.ExecuteNonQuery();

        conn.Close();
    }

0

嘿,你必须使用存储过程设置

@MiddleInitial varhcar(8) = null

+1 这个方法实际上是可行的,因为参数变成了可选项。 - Andomar

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