【问题标题】:Write bit value to database将位值写入数据库
【发布时间】:2011-07-12 15:41:45
【问题描述】:

我正在尝试将一个位值(真或假)写入我的数据库中名为“已处理”的字段中。我目前正在尝试通过传入 bool 值来做到这一点,但我收到一条错误消息,提示无法从 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();
        }






    }

【问题讨论】:

  • 你为什么不保留int01

标签: c# asp.net sql boolean bit


【解决方案1】:

需要根据真假设置位域为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 + "%'";

此外,正如 cmets 中所述,直接从用户输入构建 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();
}

【讨论】:

  • 好的,谢谢。这是我以前的情况,但我现在的问题是它实际上并没有向数据库写入任何内容......我假设需要查看更多代码?
  • 一个问题(我认为)是您在进行更新之前填充 DataAdapter...因此更新所做的任何更改都不会反映在 DataGrid 中的结果中。
  • 是我疯了还是大家都忽略了这种构造SQL语句的方式是SQL注入漏洞的经典例子?不仅如此,如果他解决了这个问题,他也会解决这个问题所涉及的问题......?
  • 是的,我总是要和自己争论是否在答案中提到这些事情。由于从技术上讲,问题是关于特定问题,而不是“这有什么问题”,因此我选择在这种情况下忽略它。
  • 我听到了。如果您编辑答案以提及漏洞,我可以删除 -1(此时已锁定)。
【解决方案2】:

虽然如果将“1”表示 True 和“0”表示 False 注入 SQL 语句字符串确实可以解决问题,但解决此问题的“正确”方法是参数化 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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 嗯,我这样做了,但它以前不起作用。我想我可以再试一次。
    • 它应该可以工作,确保你没有在数字周围加上引号。
    • 问题是它实际上并没有向数据库写入任何内容:/ 我猜 1 和 0 正在注册为位值,但它不会写出来。
    【解决方案4】:

    您的 SQL 语法错误 - 您传递了一个字符串作为将 processed 列值设置为的值,这是您无法做到的。

    【讨论】:

      【解决方案5】:

      最简单的方法是 Convert.ToInt16 您的布尔值。这将使真/假,0或1。

      【讨论】:

        【解决方案6】:

        布尔值被连接为“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 + "%'";
        

        【讨论】:

          【解决方案7】:

          您的 SQL 语句没有尝试设置任何类型的布尔值,而是尝试设置文本 %True%%False%

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

          或者,在这种特殊情况下,您可以跳过插值 trueBool,而只使用大多数其他答案所建议的完全恒定的字符串。

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

          【讨论】:

            猜你喜欢
            • 2017-01-22
            • 2017-02-19
            • 1970-01-01
            • 2021-05-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-18
            相关资源
            最近更新 更多