我正在尝试在名为“processed”的字段中将一个值(true或false)写入我的数据库。我目前正试图通过传入bool值来做到这一点,但我得到一个错误,说无法从varchar类型转换为bit。任何人都可以看到我的逻辑中发生了什么吗?
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 :(得分:6)
您需要将位字段设置为1
或0
,具体取决于它是真还是假。
所以:
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
电话
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();
}
答案 1 :(得分:3)
如果您将SQL语句字符串“1”注入True并将“0”注入False,那么您将解决您的问题,而解决此问题的“正确”方法是参数化您的SQL语句并添加命令对象的参数。然后,框架将完成从VB Boolean
到SqlDbType.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
答案 2 :(得分:2)
在SQL中,位值为1或0,而不是“true”或“false”。在更新中将'true'和'false'更改为1和0,您应该没问题。 (注意0和1也没有引号。)
答案 3 :(得分:0)
您的SQL语法错误 - 您传递一个字符串作为设置processed
列值的值,这是您无法做到的。
答案 4 :(得分:0)
最简单的方法是将Convert.ToInt16作为布尔值。这将使真/假,0或1。
答案 5 :(得分: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 + "%'";
答案 6 :(得分:0)
您的SQL语句并未尝试设置任何类型的布尔值,而是尝试设置文本%True%
或%False%
。
由于您将数据库字段描述为“位”而不是“布尔”,因此在构造字符串时可能需要使用"processed = " + (trueBool ? 1 : 0) + "
之类的内容。但是,根据您使用的SQL服务器,您可以使用processed = " + trueBool + "
或processed = '" + trueBool + "'
之类的内容。
或者,在这种特殊情况下,您可以跳过插值trueBool
并使用完全常量字符串,因为大多数其他答案都已建议。
另外,顺便说一句,请注意,通过将未经检查的用户输入插入到SQL语句中,您将自行处于错误和SQL注入状态。例如,如果有人输入“O'Brian”作为姓氏,您将收到错误,并且有更多恶意的值选择,他们可能会改变数据库中的任何内容。