【问题标题】:ASP.NET ERROR: SqlCommand.Prepare method requires all variable length parameters to have an explicitly set non-zero Size [duplicate]ASP.NET 错误:SqlCommand.Prepare 方法要求所有可变长度参数具有显式设置的非零大小 [重复]
【发布时间】:2017-12-24 07:19:35
【问题描述】:

首先,我必须把明显的事情排除在外;我已经搜索过同样的问题,StackOverFlow 上有这个问题的答案,但它对我没有用。

问题:我收到一个错误

SqlCommand.Prepare 方法要求所有可变长度参数具有显式设置的非零大小

与此声明一致

cmd.Prepare();

数据库架构:

代码:

//alreadyAnsweredQues is Global -- List<Int32>
var parameters = new string[alreadyAnsweredQues.Count];
var cmd = new SqlCommand();

for (int i = 0; i < alreadyAnsweredQues.Count; i++)
{
    parameters[i] = string.Format("@qid{0}", i);

    cmd.Parameters.Add(parameters[i].ToString(), SqlDbType.Int).Value = alreadyAnsweredQues[i];
}

cmd.Parameters.Add("@cid", SqlDbType.Int).Value = Convert.ToInt32(Session["c_id"].ToString());

cmd.CommandText = string.Format("SELECT TOP 1 * FROM questions WHERE c_id = @cid AND q_id NOT IN ({0}) ORDER BY NEWID() ;", string.Join(", ", parameters));
System.Diagnostics.Debug.WriteLine(string.Format("SELECT TOP 1 * FROM questions WHERE c_id = @cid AND q_id NOT IN ({0}) ORDER BY NEWID() ;", string.Join(", ", parameters)));

cmd.Connection = new SqlConnection(ConnectionClass.constr);
cmd.Connection.Open();

cmd.Prepare();

SqlDataReader sdr = cmd.ExecuteReader();

【问题讨论】:

    标签: c# asp.net sql-server webforms


    【解决方案1】:
    for (int i = 0; i < alreadyAnsweredQues.Count; i++)
    {
        parameters[i] = string.Format("@qid{0}", i);
    
        cmd.Parameters.Add(parameters[i].ToString(), SqlDbType.Int).Value = alreadyAnsweredQues[i];
    }
    
    cmd.Parameters.Add("@cid", SqlDbType.Int).Value = Convert.ToInt32(Session["c_id"].ToString());
    

    应该改为:

    cmd.Parameters.Add("@cid", SqlDbType.Int).Value = Convert.ToInt32(Session["c_id"].ToString());
    
    for (int i = 0; i < alreadyAnsweredQues.Count; i++)
    {
        parameters[i] = string.Format("@qid{0}", i);
        cmd.Parameters.Add(parameters[i].ToString(), SqlDbType.Int).Value = alreadyAnsweredQues[i];
    }
    

    没有必要为int 指定Size,因为它具有固定的(4 字节)大小。

    我也建议你注释掉:

    cmd.Prepare();
    

    既然有minimal benefit:

    在 SQL Server 中,准备/执行模型没有意义 由于 SQL 的方式,性能优于直接执行 服务器重用执行计划

    【讨论】:

      【解决方案2】:

      您需要在每个参数对象上设置 SqlParameter.Size 属性。

      【讨论】:

      • 你能再解释一下吗..?
      • int 参数不需要这个。
      【解决方案3】:

      正如@SornelHaetir 在他的回答中所问的那样

      您需要在每个参数对象上设置 SqlParameter.Size 属性。

      之后的问题是我不知道要进入数据库的整数的大小,所以我所做的就是输入System.Int32.MaxValue,它工作正常。

      代码:

      var parameters = new string[alreadyAnsweredQues.Count];
      var cmd = new SqlCommand();
      for (int i = 0; i < alreadyAnsweredQues.Count; i++)
      {
          parameters[i] = string.Format("@qid{0}", i);
      
      
          cmd.Parameters.Add(parameters[i].ToString(), SqlDbType.Int,System.Int32.MaxValue).Value = alreadyAnsweredQues[i];
      }
      
      
      cmd.Parameters.Add("@cid", SqlDbType.Int, System.Int32.MaxValue).Value = Convert.ToInt32(Session["c_id"].ToString());
      
      
      
      cmd.CommandText = string.Format("SELECT TOP 1 * FROM questions WHERE c_id = @cid AND q_id NOT IN ({0}) ORDER BY NEWID() ;", string.Join(", ", parameters));
      System.Diagnostics.Debug.WriteLine(string.Format("SELECT TOP 1 * FROM questions WHERE c_id = @cid AND q_id NOT IN ({0}) ORDER BY NEWID() ;", string.Join(", ", parameters)));
      cmd.Connection = new SqlConnection(ConnectionClass.constr);
      cmd.Connection.Open();
      cmd.Prepare();
      

      P.S:这可能不是处理这个问题的最佳方法,但它对我有用。

      【讨论】:

      • 如果值是整数,为什么将它们作为 varchar 发送?您应该像对 @cid 参数所做的那样更改为 SqlDbType.Int (这也应该允许您删除大小组件,尽管我相信如果您必须传递它,“4”将是正确的值)。
      • System.Int32.MaxValue Size 与 MaxValue 不同
      • @mjwills,其实这段代码在一个函数里面,这个函数至少执行了10次
      猜你喜欢
      • 2013-11-29
      • 1970-01-01
      • 2012-08-09
      • 1970-01-01
      • 2019-06-20
      • 1970-01-01
      • 1970-01-01
      • 2022-09-23
      • 1970-01-01
      相关资源
      最近更新 更多