【问题标题】:SqlCommand Parameter - must declare the scalar variable "@positionX".'SqlCommand 参数 - 必须声明标量变量“@positionX”。
【发布时间】:2018-07-25 05:33:29
【问题描述】:

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

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”。' 问题是什么?提前谢谢...

【问题讨论】:

  • 为什么要添加参数然后清除它们personCmd.Parameters.Clear();
  • 那么你麻烦设置了所有参数,然后清除参数集合?您可能试图解决在循环中设置参数导致多次声明相同参数的问题,但是您以错误的方式清除/填充。 (当然,更好的办法是在循环外声明参数并在里面设置
  • 我想向数据库中插入多个数据。 X、Y、宽度、高度、置信度参数对于图像中检测到的每个人都不同。这就是为什么我每次都想清除它们...
  • 您还希望我们如何向您解释这一点?你在做“添加、清除、执行”,这不起作用,因为“执行”需要使用“添加”完成的工作。
  • @Damien_The_Unbeliever:在循环外打开和关闭连接并调用 personCmd.Parameters.Clear();在 personCmd.ExecuteNonQuery() 之后;我的代码有效。感谢您的帮助。犯了这个错误我感觉很糟糕:设置值、清除值、执行值...

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


【解决方案1】:

查看代码后;问题来了

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

【讨论】:

  • 只需将 personCmd.Parameters.Clear();在 personCmd.ExecuteNonQuery(); 之后
  • 在循环外打开和关闭连接后,我的代码可以工作。谢谢...
【解决方案2】:

除了在需要执行参数之前错误地调用 Clear 的问题之外,您的代码还有许多改进之处。

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

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 

【讨论】:

  • 想必您也打算将第二个AddWithValue 更改为Add,并可能希望链接到Can we stop using AddWithValue() already?
  • @Damien_The_Unbeliever 确实,谢谢。同意 - AWV 的类型推断不可靠。
  • 谢谢@StuartLC
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-07
  • 1970-01-01
  • 2011-11-03
  • 1970-01-01
  • 2013-07-03
  • 1970-01-01
相关资源
最近更新 更多