SqlCommand参数-必须声明标量变量“ @positionX”。

时间:2018-07-25 05:33:30

标签: c# sql .net sql-server ado.net

我知道这个问题有很多问题。也许再问一次也没用,但是尝试了很多之后,我无法找到解决方案,所以如果有人帮助我,我将非常感激。代码如下所示:

String personQuery =
    "INSERT INTO Person(X, Y, Width, Height, Confidence) VALUES (@positionX, @positionY, @width, @height, @confidence)";

SqlCommand personCmd = new SqlCommand(personQuery, connection);

foreach (var objectItem in items)
{
    if (objectItem.Type == "person")
    {

          personCmd.Parameters.AddWithValue("@positionX", objectItem.X);
          personCmd.Parameters.AddWithValue("@positionY", objectItem.Y);
          personCmd.Parameters.AddWithValue("@width", objectItem.Width);
          personCmd.Parameters.AddWithValue("@height", objectItem.Height);
          personCmd.Parameters.AddWithValue("@confidence", objectItem.Confidence);
          personCmd.Parameters.Clear();

          connection.Open();
          personCmd.ExecuteNonQuery();
          connection.Close();

    }
}

运行此代码后,出现以下错误:必须声明标量变量“ @positionX”。' 问题是什么?预先感谢...

2 个答案:

答案 0 :(得分:3)

查看代码后;问题在这里

personCmd.Parameters.Clear();

此行必须在personCmd.ExecuteNonQuery();

之后

这可以是完整的代码:

connection.Open();
    foreach (var objectItem in items)
    {
        personCmd.Parameters.AddWithValue("@positionX", objectItem.X);
        personCmd.Parameters.AddWithValue("@positionY", objectItem.Y);
        personCmd.Parameters.AddWithValue("@width", objectItem.Width);
        personCmd.Parameters.AddWithValue("@height", objectItem.Height);
        personCmd.Parameters.AddWithValue("@confidence", objectItem.Confidence);
        personCmd.ExecuteNonQuery();
        personCmd.Parameters.Clear();
    }

    connection.Close();

答案 1 :(得分:1)

除了在需要执行参数之前错误地对参数调用Clear之外,还需要对代码进行很多改进。

  • 无需在循环中继续声明和清除参数。您可以一次声明命令和参数,然后在每次循环迭代时重新分配值
  • 与其在循环中检查项目类型,不如在迭代foreach之前过滤掉所有不需要的项目。
  • 由于命令和连接为IDisposable,因此在using语句中确定作用域和命令的连接将保证尽快释放任何代码路径的资源,包括异常。
  • 由于此代码是I / O密集型代码,因此,如果可能,请将代码切换为async以简化线程池的使用。所有ADO.Net方法的Async版(即OpenAsyncExecuteNonQueryAsync等都可以await编辑)

const string personQuery = "INSERT INTO Person(X, Y, Width, Height, Confidence) " +
                           "VALUES (@positionX, @positionY, @width, @height, @confidence)";

// Define a long lived connection and command. Both are Disposable.
using (var connection = new SqlConnection(myConnectionString))
using (var personCmd = new SqlCommand(personQuery, connection))
{
    // Open the connection just the once
    connection.Open();

    // Define the command parameters without assigning them yet
    // Check the data types against your Sql schema ...
    personCmd.Parameters.Add("@positionX", SqlDbType.Int);
    personCmd.Parameters.Add("@positionY", SqlDbType.Int);
    ... etc other parameters

    // Filter the objects before you loop them. 
    // Better would be .Where(i => i is Person) if you have subclasses
    foreach (var objectItem in items.Where(i => i.Type == "person")) 
    {
        personCmd["@positionX"].Value = objectItem.X;
        personCmd["@positionY"].Value = objectItem.Y;
        ... assign other params
        personCmd.ExecuteNonQuery();
    }
} // personCmd and connection will be automatically closed