【问题标题】:Procedure or function expects parameter, which was not supplied. A nullable column throwing exception过程或函数需要未提供的参数。可空列抛出异常
【发布时间】:2013-09-12 08:35:04
【问题描述】:

我正在使用存储过程在 sql db 中创建/更新记录。我从我的 C# 数据访问层提供了大约 30 个参数。 sql 表除了其主键列之外,所有列都可以为空。在这里,当我向可空列提供空值时,它会引发“过程或函数'spFullUpdate'需要参数'@App1TAPAYears',未提供。”的异常。在我的 c# 代码中,我可以清楚地看到该列提供了一个空值。请任何人告诉我如何纠正这个问题。 以下是我的代码 sn-p。 数据对象的设置值如下

Dt.TimeAtPreviousAddressYears = int.TryParse(TimeatPreviousAddressYears.Text, out intOut) ? intOut : (int?)null;

以下是我的实体类中的可为空属性

        public int? TimeAtPreviousAddressYears { get; set; }

我的数据访问层添加参数代码如下

cmd.Parameters.Add("@App1TAPAYears", SqlDbType.Int).Value = dataObject.TimeAtPreviousAddressYears;
SqlDataAdapter da = new SqlDataAdapter(cmd);
                conn.Open();
                cmd.ExecuteNonQuery();

可以清楚地看到,添加了参数并将空值提供给可以为空的列,但它仍然产生异常。任何人的帮助将不胜感激。

亲切的问候

【问题讨论】:

  • 请显示您添加所有参数的代码,直到您执行 SP。 (编辑您的帖子)
  • 代码很好,因为当我为这个参数提供值时它不会产生异常。仅在值为 null 时引发异常。
  • 只是想确定一下。已经看到很多关于未提供参数的问题,这是由于在查询之前再次创建命令对象引起的。
  • 在我的例子中,命令参数创建成功。问题出在空值上。
  • 在命令参数列表中,@App1TAPAYears 的 IsNullable 属性设置为 false 并且值为“null”。

标签: c# sql stored-procedures


【解决方案1】:

nullable != DBNull.Value

所以你不能将(int?)null传递给参数值,而是传递DBNull.Value

喜欢:

if (dataObject.TimeAtPreviousAddressYears.HasValue) 
{ 
    cmd.Parameters.Add("@App1TAPAYears", SqlDbType.Int).Value =dataObject.TimeAtPreviousAddressYears;
}else
{
    cmd.Parameters.Add("@App1TAPAYears", SqlDbType.Int).Value = DBNull.Value;
}

【讨论】:

  • 我收到“无法确定条件表达式类型的错误,因为 'int?' 之间没有隐式转换?”和“System.DBNull”
  • 所以这个shortcircuit 或者这个赋值在这种情况下是行不通的,所以你需要使用经典的if else。更新了我的答案。
  • 非常感谢它现在工作正常。非常感谢您的帮助。
  • 这解决了我的问题,但这只是因为在我的存储过程中我有@paramname int NULL 而不是@paramname int = NULL d'ohh。使用等号,您可以整天从 C# 传递 null
【解决方案2】:

这是一个很烦人的问题,最近因为很久没有遇到它而把我扔了。

我决定在我的 RepositoryBase 类中添加它

    protected object ValueOrNull(object value)
    {
        return value ?? DBNull.Value;
    }

这在我的任何可选项目的实际回购代码中

cmd.Parameters.Add(new SqlParameter("@VoucherCode", SqlDbType.VarChar)).Value = ValueOrNull(promo.VoucherCode);

【讨论】:

  • 或者有更多的标记但没有额外的方法:cmd.Parameters.Add(new SqlParameter("@VoucherCode", SqlDbType.VarChar)).Value = (object)Value ?? DBNull.Value;
【解决方案3】:

你应该试试

if (dataObject.TimeAtPreviousAddressYears.HasValue) 
{ 
    cmd.Parameters.Add("@App1TAPAYears", SqlDbType.Int).Value =dataObject.TimeAtPreviousAddressYears;
}else
{
    cmd.Parameters.Add("@App1TAPAYears", SqlDbType.Int).Value = (object)DBNull.Value;
}

问题在于(如错误消息所示)条件表达式在两个分支上需要相同的类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-05
    • 2013-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多