【问题标题】:Must declare the scalar variable "@ID" for insert parameter必须为插入参数声明标量变量“@ID”
【发布时间】:2013-12-02 14:09:06
【问题描述】:

我收到错误消息,必须声明标量变量“@ID”。指向 ExecuteScalar 行。我看了一下护目镜,我认为这与 ID 的插入参数有关。然后我又读到可能有错字。在我的数据库中,我将列名声明为 ID,将数据类型声明为 int,将“Is Identity”设置为 Yes。因为我不打算手动插入 ID 列,所以我认为这就是我遇到问题的原因,我不知道如何解决这个问题。

我要做的是插入用户名、登录日期和时间。用户注销时更新同一列(同一 id 列)。当用户再次登录时创建一个新列等等。当 D Stanley 帮助我时,我正在使用我问过 herehere 的类似代码。

如果有人可以帮助我,请提前感谢。

 private int ID // forgot to add this. 
    { get; set; }

private void btnLogin_Click(object sender, RoutedEventArgs e)
    {
        string value = cbRoles.Text;

        switch (value)
        { 
            case "Manager":


                myCon.connectionString();
                string dString = string.Empty;

                SqlConnection thisConnection = myCon.dbCon;
                SqlCommand nonqueryCommand = thisConnection.CreateCommand();

                using (var command = myCon.dbCon.CreateCommand())
                {
                    command.CommandText = "SELECT * FROM tblPrivileges";
                    command.Parameters.AddWithValue("UserName", (txtUserName.Text));
                    command.Parameters.AddWithValue("Password", (txtPassword.Text));

                    thisConnection.Open();
                    var reader = command.ExecuteReader(); //strcomp
                    {
                        if (reader.HasRows)
                        {
                            while (reader.Read())
                            {
                                txtUserName.Text = reader["UserName"].ToString();
                                txtPassword.Text = reader["Password"].ToString();
                                MainWindow gobackB = new MainWindow();
                                gobackB.Show();
                                LoginSample goback = new LoginSample();
                                goback.Hide();


                            }
                        }
                        else MessageBox.Show("You have entered incorrect credentials. Please try again", "error", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                }
                myCon.dbCon.Close();

                nonqueryCommand.CommandType = CommandType.Text;
                nonqueryCommand.CommandText = "INSERT tblLoginLogTable (UserName, LoggedInDate, LoggedInTime) VALUES (@UserName, @LoggedInDate, @LoggedInTime)";
              //nonqueryCommand.Parameters.AddWithValue("@ID", SqlDbType.Int); this did not work
              //nonqueryCommand.Parameters["@ID"].Value = this.ID; this did not work
                nonqueryCommand.Parameters.AddWithValue("@UserName", txtUserName.Text);
                nonqueryCommand.Parameters.AddWithValue("@LoggedInDate", DateTime.Now);
                nonqueryCommand.Parameters.AddWithValue("@LoggedInTime", DateTime.Now.ToString("HH:mm"));
                thisConnection.Open();
                nonqueryCommand.ExecuteNonQuery(); // error pointing here
                nonqueryCommand.CommandText = "SELECT @ID = SCOPE_IDENTITY()";
                int id = (int)nonqueryCommand.ExecuteScalar();
               // int  id = Convert.ToInt32(nonqueryCommand.ExecuteScalar()); this line did not work
                this.ID = id;
                myCon.dbCon.Close();
                break;

【问题讨论】:

  • SELECT @ID = SCOPE_IDENTITY() 是干什么用的?您尝试执行此命令而不插入一个..
  • 来自 Mikes dotting blog,我认为从 D Stanley 解决方案中可以得到最近添加的记录的标识。顺便说一句,我可以看到保存在数据库中的数据。
  • 我认为你需要添加@Id 参数作为输出参数

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


【解决方案1】:

问题仍然是您尝试将相同的“范围”与两个不同的 SQL 命令一起使用。即使它们在 SQL 中的 C# 中是相同的“变量”,但它们具有不同的范围。

您需要在一个命令中执行这两个语句,并将@ID 参数添加为Output 参数,以便插入和取出标识:

nonqueryCommand.CommandType = CommandType.Text;
nonqueryCommand.CommandText = "INSERT tblLoginLogTable (UserName, LoggedInDate, LoggedInTime) VALUES (@UserName, @LoggedInDate, @LoggedInTime); " + 
                              "SELECT @ID = SCOPE_IDENTITY()";
nonqueryCommand.Parameters.AddWithValue("@UserName", txtUserName.Text);
nonqueryCommand.Parameters.AddWithValue("@LoggedInDate", DateTime.Now);
nonqueryCommand.Parameters.AddWithValue("@LoggedInTime", DateTime.Now);
nonqueryCommand.Parameters.Add("@ID",SqlDbType.Int).Direction = ParameterDirection.Output;

thisConnection.Open();
nonqueryCommand.ExecuteNonQuery(); 

int id = (int)nonqueryCommand.Parameters["@ID"];

【讨论】:

  • 最后一行的ParameterDirection和Parameters是什么? IntelliSense 没有接收到它们。
  • 好吧,你在它之前的 3 个谎言上使用了参数,所以我不确定它为什么现在抱怨 - ParameterDirection 应该只是 Direction - 我已经适当地更新了我的答案。
  • 谢谢 - 它仍然在抱怨最后一行的参数。
  • int id = (int)nonqueryCommand.Parameters["@ID"];最后需要 .value 否则它不会正确转换... int id = (int)nonqueryCommand.Parameters["@ID"].value;
【解决方案2】:

这里:

nonqueryCommand.CommandText = "SELECT @ID = SCOPE_IDENTITY()";

您的 SQL 为未声明的变量赋值。由于您使用的是ExecuteScalar,您可能只是意味着:

nonqueryCommand.CommandText = "SELECT SCOPE_IDENTITY()";

请注意,您可能需要强制转换它 - 它可能会以 decimal 的形式返回。

【讨论】:

  • 指定的演员阵容无效。?这就是您所说的“可能需要投射它”的意思。我需要进入这个,因为我不知道这意味着
  • @bucketblast 是的;试试int id = (int)(decimal)nonqueryCommand.ExecuteScalar();
  • 那也没用。我试过 nonqueryCommand.CommandText = "SELECT @@IDENTITY"; int id = System.Convert.ToInt32(nonqueryCommand.ExecuteScalar());这种工作,但同时打开两个 xaml 窗口。这是为什么?当我输入错误的用户名和密码时,它无法识别,只是打开了 windows xaml,这是为什么呢
猜你喜欢
  • 2017-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多