Ошибка обновления базы данных

62
6

У меня есть форма, которая отображает выбранные данные datagridviewrow в текстовые поля. Я хотел бы отредактировать и обновить данные из этой формы, а также обновить и сохранить в datatable, когда пользователь нажимает на обновление. Когда я нажимаю обновление, появляется сообщение об ошибке:
Произошла ошибка при анализе запроса. [Номер строки токена = 1, смещение линии токена = 25, токен с ошибкой = (]

private void editBTN_Click(object sender, EventArgs e)
{
bool notEditable = true;
if (editBTN.Text == "Update")
{
UpdateDataBase();
editBTN.Text = "Edit";
deleteBTN.Visible = true;
notEditable = true;
}
else
{
deleteBTN.Visible = false;
editBTN.Text = "Update";
deleteBTN.Visible = false;
notEditable = false;
}
firstTxt.ReadOnly = notEditable;
surenameTxt.ReadOnly = notEditable;
address1Txt.ReadOnly = notEditable;
address2Txt.ReadOnly = notEditable;
countyTxt.ReadOnly = notEditable;
contactTxt.ReadOnly = notEditable;
emailTxt.ReadOnly = notEditable;
postTxt.ReadOnly = notEditable;

}

private void UpdateDataBase()
{
if (MessageBox.Show("Customer information will be updated. This change cannot be undone. Are you sure you want to continue? ", "Confirm Edit", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
string constring = @"Data Source=|DataDirectory|\LWADataBase.sdf";
string Query = "update customersTBL set ([First_Name] = '" + this.firstTxt.Text + "',surename= '" + this.surenameTxt.Text + "',[Address Line 1] = '" + this.address1Txt.Text + "',[Address Line 2] = '" + this.address2Txt.Text + "',County = '" + this.countyTxt.Text + "',[Post Code] = '" + this.postTxt.Text + "' , Email = '" + this.emailTxt.Text + "';,[Contact Number] = '" + this.contactTxt.Text + "');";
SqlCeConnection conDataBase = new SqlCeConnection(constring);
SqlCeCommand cmdDataBase = new SqlCeCommand(Query, conDataBase);
SqlCeDataReader myReader;
try
{
conDataBase.Open();
myReader = cmdDataBase.ExecuteReader();
MessageBox.Show("Customer information has been updated", "Update Sucessful");
while (myReader.Read())
{

}
MessageBox.Show("Please exit the Customers window and re-open to update the table");
this.Close();
//displays a system error message if a problem is found
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

}

спросил(а) 2014-02-14T19:45:00+04:00 7 лет, 2 месяца назад
1
Решение
97

Я думаю, что вы запутываете структуру Update с помощью Insert.

Для вашего обновления это выглядит так:

обновить customersTBL set ([First_Name] = 'data', surename = '', [Address Line 1] = '', [Address Line 2] = '', County = '', [Post Code] = '', Email = '';, [Contact Number] = '');


Вам нужно предложение where.

Update/Set не вносит изменения в()

После электронной почты у вас есть ';'

ответил(а) 2014-02-14T19:51:00+04:00 7 лет, 2 месяца назад
62

В вашем коде есть некоторые проблемы.
Один из них тривиален и может быть легко исправлен (удалите точку с запятой до [Contact Number], но есть и другие скрытые проблемы, которые потенциально более серьезны.

    Во-первых: не забудьте всегда закрывать и удалять одноразовые объекты (соединение и команда в этом случае). Оператор using гарантирует, что объект, заключенный блоком использования, будет правильно закрыт и установлен также в случае исключений Второй: используйте параметризованный запрос. Это позволяет избежать проблем с Sql Injections и parsing. Если один или несколько ваших входных данных содержат одну цитату, конкатенация строк, используемая для сборки текста команды sql, будет вызвана недопустимой командой В-третьих: команда обновления действует на все записи, присутствующие в таблице, если вы не добавляете условие WHERE. Обычно условие WHERE добавляется, чтобы идентифицировать единственную запись, которую необходимо обновить, и это значение поля с индексом UNIQUE или PRIMARY KEY вашей таблицы. Конечно, вы можете обновить более одной записи с менее ограничительным предложением WHERE, но это, похоже, не так

    В-четвертых: используйте ExecuteNonQuery вместо ExecuteReader для команд, которые обновляют/вставляют базу данных (хорошо она работает одинаково, но зачем использовать метод, который должен быть зарезервирован для других целей?)

    private void UpdateDataBase(int customerID)
    {
    string constring = @"Data Source=|DataDirectory|\LWADataBase.sdf";
    string Query = @"update customersTBL set [First_Name] = @fname,
    surename = @sur, [Address Line 1] = @addr1,
    [Address Line 2] = @addr2, County = @county,
    [Post Code] = @pcode, Email = @mail, [Contact Number] = @ctNo
    WHERE customerID = @id";
    using(SqlCeConnection conDataBase = new SqlCeConnection(constring))
    using(SqlCeCommand cmdDataBase = new SqlCeCommand(Query, conDataBase))
    {
    try
    {
    conDataBase.Open();
    cndDataBase.Parameters.AddWithValue("@fname", this.firstTxt.Text);
    cndDataBase.Parameters.AddWithValue("@sur", this.surenameTxt.Text );
    cndDataBase.Parameters.AddWithValue("@addr1", this.address1Txt.Text );
    cndDataBase.Parameters.AddWithValue("@addr2", this.address2Txt.Text );
    cndDataBase.Parameters.AddWithValue("@county", this.countyTxt.Text );
    cndDataBase.Parameters.AddWithValue("@pcode", this.postTxt.Text );
    cndDataBase.Parameters.AddWithValue("@mail", this.emailTxt.Text );
    cndDataBase.Parameters.AddWithValue("@ctNo", this.contactTxt.Text );
    cndDataBase.Parameters.AddWithValue("@id", customerID );
    int rowsUpdated = cmdDataBase.ExecuteNonQuery();
    if(rowsUpdate == 0)
    MessageBox.Show("No customer found to update");
    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.Message);
    }
    }
    }

Как вы можете видеть, с параметризованным запросом сложнее написать плохой sql-текст со скрытыми проблемами, а задание кавычек передается в код базы данных, который лучше знает, как форматировать значения параметров.

Единственная проблема, которую вам нужно решить, - это получить значение для идентификатора customerID или другого значения, которое вы могли бы использовать в предложении WHERE, чтобы однозначно идентифицировать запись вашего клиента

В этом случае вы вызываете метод UpdateDatabase, который теперь требует переменную UserID, содержащую ключ для идентификации вашего пользователя на таблице

private void editBTN_Click(object sender, EventArgs e)
{
bool notEditable = true;
if (editBTN.Text == "Update")
{
// Here you need to identify uniquely your modified user
// Usually when you load the data to edit you have this info extracted from your
// database table and you have saved it somewhere
// (of course the user should not edit in any way this value
int UserID = ... ???? (from an hidden textbox? from a global variable, it is up to you
UpdateDataBase( UserID );

ответил(а) 2014-02-14T20:04:00+04:00 7 лет, 2 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема