Записать значение бита в базу данных - PullRequest
2 голосов
/ 12 июля 2011

Я пытаюсь записать битовое значение (true или false) в мою базу данных в поле, называемое «обработано». В настоящее время я пытаюсь сделать это, передавая значения 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();
        }






    }

Ответы [ 7 ]

6 голосов
/ 12 июля 2011

Вам необходимо установить битовые поля на 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();
}
3 голосов
/ 12 июля 2011

Хотя верно, что вы решите свою проблему, если введете в строку оператора 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();

Если вы собираетесь писать веб-приложения, управляемые данными, очень важно, чтобы вы понимали, как избежать уязвимости безопасности SQL-инъекций. Для получения дополнительной информации: MSDN Как: защитить от SQL-инъекций в ASP.NET

2 голосов
/ 12 июля 2011

В SQL значение бита равно 1 или 0, а не 'true' или 'false'. Измените 'true' и 'false' на 1 и 0 в вашем обновлении, и вы должны быть в порядке. (Обратите внимание, что 0 и 1 также не имеют кавычек.)

0 голосов
/ 12 июля 2011

Ваш оператор SQL не пытается установить какой-либо логический тип, он пытается установить текст %True% или %False%.

Поскольку вы описали поле базы данных как «бит», а не как«логическое», вам, вероятно, потребуется использовать что-то вроде "processed = " + (trueBool ? 1 : 0) + " при построении вашей строки.Но в зависимости от используемого вами SQL-сервера вы можете получить что-то вроде processed = " + trueBool + " или processed = '" + trueBool + "'.

. Или, в данном конкретном случае, вы можете пропустить интерполяцию trueBool и простоиспользуйте полностью константную строку, как предлагали большинство других ответов.

Кроме того, обратите внимание, что вы оставляете себя широко открытым для ошибок и внедрения SQL, вставляя непроверенный пользовательский ввод в ваши операторы SQL.Например, если кто-то введет «O'Brian» в качестве фамилии, вы получите ошибки, и при более злонамеренном выборе значений они могут изменить что-либо в базе данных.

0 голосов
/ 12 июля 2011

Логические значения объединяются как "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 голосов
/ 12 июля 2011

Самый простой способ сделать это - Convert.ToInt16 ваше логическое значение.Это сделает true / false, 0 или 1.

0 голосов
/ 12 июля 2011

Ваш синтаксис SQL неверен - вы передаете строку в качестве значения для установки значения столбца processed, что вы не можете сделать.

...