2011-07-12 37 views
1

我试图在称为“已处理”的字段中将一个位值(true或false)写入我的数据库中。我目前正在试图通过传递布尔值来做到这一点,但我得到一个错误,说不能从类型varchar转换为位。任何人都可以看到我的逻辑中发生了什么?将位值写入数据库

 protected void CheckBoxProcess_CheckedChanged(object sender, EventArgs e) 
    { 
     bool update; 
     bool trueBool = true; 
     bool falseBool = false; 
     string checkedString = "UPDATE SecureOrders SET processed = '%" + trueBool + "%' WHERE fName LIKE '%" + DefaultGrid.SelectedRow.Cells[2].Text + "%' AND lName LIKE '% " + DefaultGrid.SelectedRow.Cells[3].Text + "%'"; 
     string uncheckedString = "UPDATE SecureOrders SET processed = '%" + falseBool + "%' WHERE fName LIKE '%" + DefaultGrid.SelectedRow.Cells[2].Text + "%' AND lName LIKE '% " + DefaultGrid.SelectedRow.Cells[3].Text + "%'"; 
     CheckBox cb = (CheckBox)sender; 
     GridViewRow gvr = (GridViewRow)cb.Parent.Parent; 
     DefaultGrid.SelectedIndex = gvr.RowIndex; 
     update = Convert.ToBoolean(DefaultGrid.SelectedValue); 

     orderByString = orderByList.SelectedItem.Value; 
     fieldString = searchTextBox.Text; 


     System.Configuration.ConnectionStringSettings connectionString; 

     connectionString = rootWebConfig.ConnectionStrings.ConnectionStrings["secureodb"]; 



     // Create an SqlConnection to the database. 
     using (SqlConnection connection = new SqlConnection(connectionString.ToString())) 
     { 
      connection.Open(); 
      SqlCommand checkedCmd = new SqlCommand(checkedString, connection); 
      SqlCommand uncheckedCmd = new SqlCommand(uncheckedString, connection); 
      dataAdapter = new SqlDataAdapter("SELECT * FROM SecureOrders", connection); 

      // create the DataSet 
      dataSet = new DataSet(); 
      // fill the DataSet using our DataAdapter    
      dataAdapter.Fill(dataSet, "SecureOrders"); 

      DataView source = new DataView(dataSet.Tables[0]); 
      DefaultGrid.DataSource = source; 


      if (cb.Checked == true) 
      { 
       checkedCmd.ExecuteNonQuery(); 

      } 
      else 
      { 
       uncheckedCmd.ExecuteNonQuery(); 
      } 

      connection.Close(); 
     } 






    } 
+0

为什么不ü保持'int'和''0' 1'? – Sudantha

回答

5

您需要将位字段设置为10,具体取决于它是true还是false。

所以:

string checkedString = "UPDATE SecureOrders SET processed = 1 WHERE fName LIKE '%" + DefaultGrid.SelectedRow.Cells[2].Text + "%' AND lName LIKE '% " + DefaultGrid.SelectedRow.Cells[3].Text + "%'"; 
string uncheckedString = "UPDATE SecureOrders SET processed = 0 WHERE fName LIKE '%" + DefaultGrid.SelectedRow.Cells[2].Text + "%' AND lName LIKE '% " + DefaultGrid.SelectedRow.Cells[3].Text + "%'"; 

而且,正如在评论中提到的,直接从用户输入构造SQL语句是牺牲品SQL注入攻击的最简单方法。在这些情况下,最好使用参数化查询(甚至是存储过程)。

.... 
string checkedString = "UPDATE SecureOrders SET processed = 1 WHERE fName LIKE @p1 AND lName LIKE @p2"; 
string uncheckedString = "UPDATE SecureOrders SET processed = 0 WHERE fName LIKE @p1 AND lName LIKE @p2"; 

然后,您可以创建参数传递给你的ExecuteNonQuery调用做,这是你的Convert.ToInt16布尔值

SqlParameter p1 = new SqlParameter("@p1",SqlDbType.Varchar) { Value = string.Format("%{0}%",DefaultGrid.SelectedRow.Cells[2].Text) }; 
SqlParameter p2 = new SqlParameter("@p2",SqlDbType.Varchar) { Value = string.Format("%{0}%",DefaultGrid.SelectedRow.Cells[3].Text) }; 
if (cb.Checked == true) 
{ 
    checkedCmd.Parameters.Add(p1); 
    checkedCmd.Parameters.Add(p2); 
    checkedCmd.ExecuteNonQuery(); 

} 
else 
{ 
    uncheckedCmd.Parameters.Add(p1); 
    uncheckedCmd.Parameters.Add(p2); 
    uncheckedCmd.ExecuteNonQuery(); 
} 
+0

好的,谢谢。这是我有过,但现在我的问题是,它实际上没有任何内容写入数据库...我假设更多的代码将需要看到的? –

+0

一个问题(我认为)是您填写您的DataAdapter你做你的更新...因此由更新所做的任何更改将不会在DataGrid的结果反映了。 – ckramer

+0

我疯了还是被大家忽略了一个事实,即构建SQL语句的方式是SQL注入漏洞的经典例子?不仅如此,但如果他解决了这个问题,他也会解决这个问题是关于......? – pseudocoder

2

在SQL的比特值是1或0,而不是 '真' 或 '假'。在更新中将“true”和“false”更改为1和0,您应该没问题。 (请注意,0和1也没有引号。)

+0

嗯,我做到了,但之前没有工作。我想我可以再试一次。 –

+0

它应该工作,确保你没有引号。 – DaveShaw

+0

的问题是,它实际上没有任何内容写入数据库:/的1和0注册为位值精我想,但不会写出来。 –

0

您的SQL语法错误 - 您正在传递一个字符串作为将processed列值设置为的值,这是您无法执行的操作。

0

最简单的方法。这将使真/假,0或1.

0

布尔值被连接为“true”|“false”。尝试使用三元操作钮显示“1”或“0”:

string checkedString = "UPDATE SecureOrders SET processed = '%" + (trueBool ? "1" : "0") + "%' WHERE fName LIKE '%" + DefaultGrid.SelectedRow.Cells[2].Text + "%' AND lName LIKE '% " + DefaultGrid.SelectedRow.Cells[3].Text + "%'"; 
0

你的SQL语句是不是要设置任何形式的布尔的,它试图设置文本%True%%False%

由于您将数据库字段描述为“位”而不是“布尔”,因此在构建字符串时可能需要使用类似"processed = " + (trueBool ? 1 : 0) + "的内容。但取决于您使用的SQL服务器,您可能能够脱离processed = " + trueBool + "processed = '" + trueBool + "'之类的东西。

或者,在这种特殊情况下,您可以跳过插值trueBool,并使用完全常量字符串,因为大多数其他答案都提示过。

另外,顺便说一下,请注意,通过将未经检查的用户输入内插到您的SQL语句中,您将为自己的错误和SQL注入敞开大门。例如,如果有人输入“O'Brian”作为姓,你将会得到错误,并且如果有更多的恶意值选择,他们可能会改变数据库中的任何内容。

3

虽然确实如果你注入SQL语句字符串“1”为真,“0”为假,你将解决你的问题,解决这个问题的“正确”方法是参数化你的SQL语句和将参数添加到命令对象。然后由框架完成从VB BooleanSqlDbType.Bit的类型转换。

尝试:

string sqlString = "UPDATE SecureOrders SET processed = @Processed WHERE fName LIKE '%' + @FirstName + '%' AND lName LIKE '%' + @LastName + '%'"; 

和:

 SqlCommand objCmd = new SqlCommand(sqlString, connection); 
     objCmd.Parameters.AddWithValue("Processed", cb.Checked); 
     objCmd.Parameters.AddWithValue("FirstName", DefaultGrid.SelectedRow.Cells[2].Text); 
     objCmd.Parameters.AddWithValue("LastName", DefaultGrid.SelectedRow.Cells[3].Text); 

最后:

objCmd.ExecuteNonQuery(); 

如果你将要写入数据驱动的web应用程序是非常重要的,你知道如何避免SQL注入安全漏洞。欲了解更多信息:MSDN How To: Protect From SQL Injection in ASP.NET