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

时间:2017-12-24 07:19:35

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

首先,我必须采取明显的措施;我已经搜索了同样的问题,在StackOverFlow上有这个问题的答案,但它对我没有用。

问题:我收到错误

  

SqlCommand.Prepare方法要求所有可变长度参数都有明确设置的非零大小

在此声明的行上

cmd.Prepare();

数据库架构:

enter image description here

代码:

//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();

3 个答案:

答案 0 :(得分: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];
}

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

我还建议你发表评论:

cmd.Prepare();

因为有minimal benefit

  

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

答案 1 :(得分:0)

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

答案 2 :(得分:-1)

正如@SoronelHaetir在答案中所说的那样

  

您需要在每个参数对象上设置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:这可能不是解决这个问题的最佳方法,但它对我有用。