将位值写入数据库

时间:2011-07-12 15:41:46

标签: c# asp.net sql boolean bit

我正在尝试在名为“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();
        }






    }

7 个答案:

答案 0 :(得分:6)

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

所以:

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 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

答案 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”作为姓氏,您将收到错误,并且有更多恶意的值选择,他们可能会改变数据库中的任何内容。