`ql = "select ID from Users where Username = '" + txtusername.Text + "';";
cmd = new SqlCommand(sql, Sel_Menu.con);
Sel_Menu.con.Open();
IDD = int.Parse(cmd.ExecuteScalar().ToString()); //here I get int32
Sel_Menu.con.Close();
IDD = 15;
sql = "insert into Action_Log ([ID_User],[Action_NR],[AtWhatTime]) values (@iDUser,@action_NR,getdate())";
cmd = new SqlCommand(sql, Sel_Menu.con);
cmd.Parameters.AddWithValue("@iDUser", IDD+1-1);
cmd.Parameters.AddWithValue("@action_NR", 1);
cmd = new SqlCommand(sql, Sel_Menu.con);
Sel_Menu.con.Open();
cmd.ExecuteNonQuery(); //done also with cmd.ExecuteScalar(); ...
Sel_Menu.con.Close();`
我该如何解决这个问题? 我仍然“必须声明标量值”@iD_User“”错误 - 我所做的一切 - 不会改变这个错误 - 即使不是任何其他错误。
答案 0 :(得分:3)
在声明参数
之前,只需移动重新初始化SqlCommand的行 cmd = new SqlCommand(sql, Sel_Menu.con);
cmd.Parameters.AddWithValue("@iD_User",IDD);
cmd.Parameters.AddWithValue("@action_NR", 1);
cmd.Parameters.AddWithValue("@atWhatTime","getdate()");
您的代码是将参数添加到上一个cmd实例而不是实际执行的命令。另请注意,方法SqlParameterCollection.Add(string,SqlDbType,int)表示添加名称,类型和SIZE的参数。但它没有设置参数的值。
还有另一个错误。 getDate()函数是一个T-SQL函数。在编写它时,您将字符串"getDate()"
传递给最后一个参数。直接在Sql命令文本中移动它并删除第三个参数。
sql = @"insert into Action_Log (ID_User,Action_NR,AtWhatTime) values
(@iD_User,@action_NR,getDate())";
最后但并非最不重要。在此查询中,您使用参数化方法(好),而第一个使用字符串连接(坏)。使用always参数来避免Sql Injection和解析问题。
答案 1 :(得分:2)
在向命令添加参数之前,应该发出语句cmd = new SqlCommand(sql, Sel_Menu.con);
。
由于您使用单个对象cmd
来执行这两个命令,因此它会向先前的引用添加参数,稍后当您使用new SqlCommand(sql, Sel_Menu.con)
再次初始化它时,您的参数将丢失。
sql = "insert into Action_Log (ID_User,Action_NR,AtWhatTime) values (@iD_User,@action_NR,@atWhatTime)";
cmd = new SqlCommand(sql, Sel_Menu.con);
cmd.Parameters.AddWithValue("@iD_User",SqlDbType.Int, IDD); //I had also tried: "cmd.Parameters.AddWithValue("@iD_User", IDD)"
cmd.Parameters.AddWithValue("@action_NR", 1);
cmd.Parameters.AddWithValue("@atWhatTime",DateTime.Now);
// Either pass `getdate` in your string query or send `DateTime.Now` as parameter.
//Note that DateTime.Now could result in a different value than getdate.
//Thanks to @Steve answer
考虑在第一个命令中使用参数,否则您的代码很容易SQL Injection。还要考虑在using
语句中包含您的命令和连接对象,以确保资源的处置。
答案 2 :(得分:2)
在尝试添加参数之前,需要初始化cmd
。在参数行之前移动此行。
cmd = new SqlCommand(sql, Sel_Menu.con);
而SqlParameterCollection.Add(String, SqlDbType, Int32)
overload将size
作为第三个参数value
。您可能需要使用other overloads。
您应始终使用parameterized queries。这种字符串连接对SQL Injection攻击开放。
顺便说一下,使用using
statement来处理数据库连接和命令。