【问题标题】:SqlCommand.Parameters.AddWithValue issue: Procedure or function X expects parameter @Y, which was not suppliedSqlCommand.Parameters.AddWithValue 问题:过程或函数 X 需要参数 @Y,但未提供
【发布时间】:2011-02-16 08:46:54
【问题描述】:

下面的代码有问题。我正在将参数 (List<SqlParameter>) 传递给执行以下代码的方法。

当它执行时,SQL Server 会抛出一个错误,指出 proc 需要一个未提供的参数。我知道这个错误并理解它,当单步执行代码时,我可以看到cmdExecuteReader 对象有一组具有正确名称和值的参数。可能是什么问题?

     public SqlDataReader ExecuteReader(string storedProcedure, List<SqlParameter> parameters = null)
        {
                    SqlCommand cmdExecuteReader = new SqlCommand()
                    {
                        CommandType = System.Data.CommandType.Text,
                        Connection = conn,
                        CommandText = storedProcedure
                    };

                    if (parameters != null)
                    {
                        foreach (SqlParameter param in parameters)
                        {
                            cmdExecuteReader.Parameters.AddWithValue(param.ParameterName, param.Value);
                        }
                    }

                    if (conn.State == System.Data.ConnectionState.Closed)
                        conn.Open();
                    return cmdExecuteReader.ExecuteReader();
       }

【问题讨论】:

    标签: c# parameters sqlcommand


    【解决方案1】:

    任何参数的.Value 是否设置为null?如果是这样,它们不会被发送。试试:

    cmdExecuteReader.Parameters.AddWithValue(param.ParameterName,
            param.Value ?? DBNull.Value);
    

    (注意与DBNull.Value 的空合并)

    另外,请注意AddWithValue 可能会影响您的查询计划重用,因为(对于字符串等)它使用 的长度。如果您需要最大性能,最好使用定义的尺寸手动设置参数。

    还要注意可能传入列表中的一些参数可能是输入-输出、输出或结果。我很想用类似的东西代替:

    SqlParameter newParam = cmdExecuteReader.Parameters.Add(
          param.ParameterName, param.SqlDbType, param.Size);
    newParam.Value = param.Value ?? DBNull.Value;
    newParam.Direction = param.Direction;
    

    【讨论】:

    • +1。我个人不使用 AddWithValue,更喜欢显式定义数据类型(和大小) - 否则您最终可能会做出不正确的假设(例如 .NET 字符串值作为 NVARCHAR 传入),我对此感到偏执
    【解决方案2】:

    我做了你想做的事情,这里有一些例子:

    public int ChangeState(int id, int stateId)
    {
        return DbUtil.ExecuteNonQuerySp("changeDossierState", Cs, new { id, stateId });
    }
    
    public IEnumerable<Dossier> GetBy(int measuresetId, int measureId, DateTime month)
    {
        return DbUtil.ExecuteReaderSp<Dossier>("getDossiers", Cs, new { measuresetId, measureId, month });
    }
    

    推荐你看here

    并下载示例解决方案(其中包含 DAL 示例项目) http://valueinjecter.codeplex.com/

    【讨论】:

      猜你喜欢
      • 2017-05-06
      • 1970-01-01
      • 1970-01-01
      • 2013-09-09
      • 2020-12-14
      • 2020-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多