我被建议用SqlParameter
替换我的代码以避免SQL注入作为安全问题,但我的理解有限。我尝试实施它,但我遇到了一个错误:
必须声明标量变量
我已经尝试了其他线程的其他建议,即为每次插入实现一个新参数,而不是替换每个条目的参数值。
String query = "INSERT INTO EmpInfo(EmpYear, EmpStatus, LName, FName, JobTitle, EmpPay, EmpDoB, EmpSex, EmpAddr, EmpCity, EmpState, EmpZIP, EmpCountry, EmpEAddr, EmpTelNo, EmpMobileNo, EmpDate) " +
"VALUES('"+EmpYear+"', @EmpStatus, @LName, @FName, @JobTitle, @EmpPay, @EmpDoB, @EmpSex, @EmpAddr, @EmpCity, @EmpState, @EmpZIP, @EmpCountry, @EmpEAddr, @EmpTelNo, @EmpMobileNo, getdate())";
String query2 = "INSERT INTO AccountInfo(LName, FName, EmpTemplate, AccountType, EmpStatus, EmpDate) " +
"VALUES (@LName, @FName, @EmpTemplate, @AccountType, @EmpStatus, GetDate())";
using (SqlConnection connection = new SqlConnection("Data Source=RB-DESKTOP;Initial Catalog=TimeDB;Persist Security Info=True;User ID=sa;Password=bautista7"))
{
SqlCommand cmd = new SqlCommand(query, connection);
cmd.Connection = conn;
conn.Open();
cmd.CommandText = "SELECT MAX(EmpID) FROM EmpInfo";
SqlDataReader rdr = cmd.ExecuteReader();
rdr.Close();
SqlCommand command = new SqlCommand(query, cmd.Connection);
command.Parameters.Add(new SqlParameter() { ParameterName = "@EmpYear", Value = EmpYear });
command.Parameters.Add(new SqlParameter() { ParameterName = "@EmpStatus", Value = "Active" });
command.Parameters.Add(new SqlParameter() { ParameterName = "@LName", Value = regLname_text.Text });
command.Parameters.Add(new SqlParameter() { ParameterName = "@FName", Value = regFname_text.Text });
command.Parameters.Add(new SqlParameter() { ParameterName = "@JobTitle", Value = "NULL" });
command.Parameters.Add(new SqlParameter() { ParameterName = "@EmpPay", Value = PayType_cb.SelectedItem.ToString() });
command.Parameters.Add(new SqlParameter() { ParameterName = "@EmpDoB", Value = regDob_dtp.Value.Date });
command.Parameters.Add(new SqlParameter() { ParameterName = "@EmpSex", Value = gender });
command.Parameters.Add(new SqlParameter() { ParameterName = "@EmpAddr", Value = regAddr_text.Text });
command.Parameters.Add(new SqlParameter() { ParameterName = "@EmpCity", Value = regCity_text.Text });
command.Parameters.Add(new SqlParameter() { ParameterName = "@EmpState", Value = regState_text.Text });
command.Parameters.Add(new SqlParameter() { ParameterName = "@EmpZIP", Value = regZip_text.Text });
command.Parameters.Add(new SqlParameter() { ParameterName = "@EmpCountry", Value = regCountry_text.Text });
command.Parameters.Add(new SqlParameter() { ParameterName = "@EmpEAddr", Value = regEmail_text.Text });
command.Parameters.Add(new SqlParameter() { ParameterName = "@EmpTelNo", Value = regTel_text.Text });
command.Parameters.Add(new SqlParameter() { ParameterName = "@EmpMobileNo", Value = regMob_text.Text });
command.ExecuteNonQuery();
command.Parameters.Clear();
SqlCommand command2 = new SqlCommand(query2, cmd.Connection);
command.Parameters.AddWithValue("@LName", regLname_text.Text);
command.Parameters.AddWithValue("@FName", regFname_text.Text);
command.Parameters.AddWithValue("@EmpTemplate", template);
command.Parameters.AddWithValue("@AccountType", AcctType_cb.SelectedItem.ToString());
command.Parameters.AddWithValue("@EmpStatus", "Active");
command.ExecuteNonQuery();
command.Parameters.Clear();
答案 0 :(得分:0)
我认为你应该先尝试简化你的逻辑。我发现了几件奇怪的事情。
查询已"VALUES('"+EmpYear+"',
我认为您需要@EmpYear
,因为您还有
command.Parameters.Add(new SqlParameter() { ParameterName = "@EmpYear", Value = EmpYear });
此外
SqlCommand cmd = new SqlCommand(query, connection);
//^^^ here you use insert query
cmd.Connection = conn;
conn.Open();
cmd.CommandText = "SELECT MAX(EmpID) FROM EmpInfo"; // But here you change it for a SELECT?
// Then you execeute a DataReader but you close it before save the result.
SqlDataReader rdr = cmd.ExecuteReader();
rdr.Close();
//Then create the insert command again
SqlCommand commad = new SqlCommand(query, cmd.Connection);
....
// clear command, I guess you want reuse it
command.Parameters.Clear();
// now create command 2 is OK
SqlCommand command2 = new SqlCommand(query2, cmd.Connection);
// ^^^ second insert query
// but add parameteres to command NOT OK
command.Parameters.AddWithValue("@LName", regLname_text.Text);
答案 1 :(得分:0)
创建command
后,您使用command2
变量两次而不是command2
。您收到错误是因为您清除了所有参数的command
,然后添加了参数(与现有查询不匹配),然后执行ExecuteNonQuery
,然后抛出错误。
更改第二个执行语句/命令,注意在创建command2
之后,现在也使用它而不是重用command
。
SqlCommand command2 = new SqlCommand(query2, cmd.Connection);
command2.Parameters.AddWithValue("@LName", regLname_text.Text);
command2.Parameters.AddWithValue("@FName", regFname_text.Text);
command2.Parameters.AddWithValue("@EmpTemplate", template);
command2.Parameters.AddWithValue("@AccountType", AcctType_cb.SelectedItem.ToString());
command2.Parameters.AddWithValue("@EmpStatus", "Active");
var numberOfRecordsInserted = command2.ExecuteNonQuery();
// value of numberOfRecordsInserted should be 1
当您使用SqlCommand
完成后可以处理它时,除非您计划重复使用完全相同的SqlCommand.Parameters.Clear()
实例,否则无需调用SqlCommand
(至少不在发布的代码中)。