Назад Вперед Зміст

Редагування запису в таблиці бази даних. ADO.NET

Для заміни запису в таблиці Книги з використанням ADO.NET необхідно виконати операцію UPDATE. Ми додамо елементи керування на форму для введення даних, які потрібно оновити, та кнопку для виконання оновлення запису.

Розмітка форми (попередньо копіюємо попередній проект)

    Додайте на форму такі елементи керування:

  1. TextBox для введення ID книги, яку потрібно оновити, з ім'ям textBoxID.
  2. TextBox для введення автора книги з ім'ям textBoxAuthor.
  3. TextBox для введення назви книги з ім'ям textBoxTitle.
  4. TextBox для введення видавництва книги з ім'ям textBoxOwner.
  5. TextBox для введення серії книги з ім'ям textBoxSeriy.
  6. TextBox для введення року видання книги з ім'ям textBoxYearPublished.
  7. TextBox для введення ціни книги з ім'ям textBoxCena.
  8. Button для оновлення запису з ім'ям buttonUpdateBook.

Код форми. Пояснення коду

  1. Ініціалізація компонентів: У конструкторі форми ініціалізуються DataSet та BindingSource.
  2. Завантаження даних: Метод LoadBooks використовується для завантаження даних з таблиці Книги та заповнення DataSet. Потім дані прив'язуються до BindingSource, який пов'язаний з DataGridView.
    using System;
    using System.Data;
    using System.Data.OleDb;
    using System.Windows.Forms;
    
    namespace SUBD
    {
        public partial class Form1 : Form
        {
            // Рядок підключення до бази даних Access
            // Виправлено помилку у шляху (замінено | на \)
            private string connectionString = @"Provider=Microsoft.ACE.OLEDB.16.0;Data Source=[DataDirectory]\KHMTM.mdb";
            
            // Джерело даних для прив'язки
            private BindingSource bindingSource;
    
            public Form1()
            {
                InitializeComponent();
                
                // Ініціалізація джерела даних
                bindingSource = new BindingSource();
                
                // Додаткові налаштування форми можна додати тут
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                try
                {
                    // Налаштування прив'язки даних для DataGridView
                    dataGridView1.DataSource = bindingSource;
                    
                    // Завантаження даних при старті форми
                    LoadBooks();
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"Помилка при ініціалізації форми: {ex.Message}", 
                                  "Помилка", 
                                  MessageBoxButtons.OK, 
                                  MessageBoxIcon.Error);
                }
            }
    
            private void LoadBooks()
            {
                using (OleDbConnection connection = new OleDbConnection(connectionString))
                {
                    try
                    {
                        connection.Open();
                        
                        // SQL-запит для отримання даних
                        string query = "SELECT * FROM Книги";
                        OleDbDataAdapter adapter = new OleDbDataAdapter(query, connection);
                        
                        // Оновлення даних через BindingSource
                        DataTable dataTable = new DataTable();
                        adapter.Fill(dataTable);
                        bindingSource.DataSource = dataTable;
                        
                        // Додаткові налаштування DataGridView
                        dataGridView1.AutoResizeColumns();
                        dataGridView1.Refresh();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"Помилка завантаження даних: {ex.Message}", 
                                      "Помилка бази даних", 
                                      MessageBoxButtons.OK, 
                                      MessageBoxIcon.Error);
                    }
                }
            }
        }
    }
     
  3. Обробник події кнопки "Відобразити дані таблиці": Метод buttonLoadData_Click викликається при натисканні кнопки "Відобразити дані таблиці". Він відображає всі записи таблиці в DataGridView.
    private void buttonLoadData_Click(object sender, EventArgs e)
    {
        // Встановлення курсору очікування
        Cursor.Current = Cursors.WaitCursor;
        
        using (OleDbConnection connection = new OleDbConnection(connectionString))
        {
            try
            {
                // Відкриття з'єднання з базою даних
                connection.Open();
                
                // Створення адаптера даних
                using (OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM Книги", connection))
                {
                    // Створення та заповнення таблиці даних
                    DataTable dataTable = new DataTable();
                    adapter.Fill(dataTable);
                    
                    // Прив'язка даних до DataGridView
                    dataGridView1.DataSource = dataTable;
                    
                    // Налаштування відображення стовпців
                    dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
                }
                
                // Повідомлення про успішне завантаження
                toolStripStatusLabel1.Text = $"Завантажено {dataGridView1.RowCount} книг";
            }
            catch (Exception ex)
            {
                // Обробка помилок
                MessageBox.Show($"Помилка завантаження даних: {ex.Message}", 
                              "Помилка", 
                              MessageBoxButtons.OK, 
                              MessageBoxIcon.Error);
                toolStripStatusLabel1.Text = "Помилка завантаження даних";
            }
            finally
            {
                // Відновлення стандартного курсору
                Cursor.Current = Cursors.Default;
            }
        }
    }
    
    private void buttonExit_Click(object sender, EventArgs e)
    {
        // Підтвердження виходу
        DialogResult result = MessageBox.Show("Ви впевнені, що хочете закрити програму?",
                                            "Підтвердження виходу",
                                            MessageBoxButtons.YesNo,
                                            MessageBoxIcon.Question);
        
        if (result == DialogResult.Yes)
        {
            Application.Exit();
        }
    }
     
  4. Обробник події кнопки: Метод buttonUpdateBook_Click викликається при натисканні кнопки "Змінити запис". Він перевіряє, що всі поля заповнені коректно, і викликає метод UpdateBookById для зміни запису.
  5. Для роботи з грошовими значеннями в базі даних Access та їх правильної відповідності в ADO.NET необхідно використовувати відповідний тип даних. У Access грошові значення зазвичай мають тип даних Currency. В ADO.NET тип даних, який використовується для роботи з грошовими значеннями, це OleDbType.Currency.
  6. Щоб оновити лише ті поля в таблиці Книги, текстові поля для яких заповнені, можна побудувати SQL-запит динамічно, додаючи лише ті поля, які мають значення.
    1. Створити базовий запит: Почніть з базового запиту на оновлення.
    2. Перевірити кожне текстове поле: Додайте відповідні частини SQL-запиту, якщо текстове поле заповнене.
    3. Виконати запит: Виконайте динамічно створений SQL-запит.
    private void UpdateBookById(int id)
    {
        using (OleDbConnection connection = new OleDbConnection(connectionString))
        {
            try
            {
                connection.Open();
                
                // Початок SQL-запиту
                string query = "UPDATE Книги SET ";
                List setClauses = new List();
                List parameters = new List();
                
                // Перевірка та додавання полів для оновлення
                if (!string.IsNullOrWhiteSpace(textBoxAuthor.Text)) 
                {
                    setClauses.Add("Автор = @Author");
                    parameters.Add(new OleDbParameter("@Author", textBoxAuthor.Text));
                }
                
                if (!string.IsNullOrWhiteSpace(textBoxTitle.Text)) 
                {
                    setClauses.Add("Название = @Title");
                    parameters.Add(new OleDbParameter("@Title", textBoxTitle.Text));
                }
                
                if (!string.IsNullOrWhiteSpace(textBoxOwner.Text)) 
                {
                    setClauses.Add("Издательство = @Owner");
                    parameters.Add(new OleDbParameter("@Owner", textBoxOwner.Text));
                }
                
                if (!string.IsNullOrWhiteSpace(textBoxSeriy.Text)) 
                {
                    setClauses.Add("Серия = @Seriy");
                    parameters.Add(new OleDbParameter("@Seriy", textBoxSeriy.Text));
                }
                
                if (!string.IsNullOrWhiteSpace(textBoxYearPublished.Text)) 
                {
                    setClauses.Add("[Год издания] = @YearPublished");
                    parameters.Add(new OleDbParameter("@YearPublished", textBoxYearPublished.Text));
                }
                
                if (!string.IsNullOrWhiteSpace(textBoxCena.Text)) 
                {
                    setClauses.Add("Цена = @Cena");
                    parameters.Add(new OleDbParameter("@Cena", textBoxCena.Text));
                }
                
                // Перевірка наявності полів для оновлення
                if (setClauses.Count == 0)
                {
                    MessageBox.Show("Не вказано жодного поля для оновлення.", 
                                  "Попередження", 
                                  MessageBoxButtons.OK, 
                                  MessageBoxIcon.Warning);
                    return;
                }
                
                // Додаємо умову WHERE до запиту
                query += string.Join(", ", setClauses) + " WHERE Код_книги = @ID";
                parameters.Add(new OleDbParameter("@ID", id));
                
                // Виконання запиту
                using (OleDbCommand command = new OleDbCommand(query, connection))
                {
                    command.Parameters.AddRange(parameters.ToArray());
                    int rowsAffected = command.ExecuteNonQuery();
                    
                    MessageBox.Show($"Оновлено {rowsAffected} запис(ів).", 
                                  "Результат оновлення", 
                                  MessageBoxButtons.OK, 
                                  MessageBoxIcon.Information);
                    
                    // Оновлення відображення даних
                    LoadBooks();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Помилка при оновленні даних: {ex.Message}", 
                              "Помилка бази даних", 
                              MessageBoxButtons.OK, 
                              MessageBoxIcon.Error);
            }
        }
    }
     
    1. Створюємо базовий запит: Ініціалізуємо запит з UPDATE Книги SET.
    2. Перевіряємо кожне текстове поле: Для кожного текстового поля (наприклад, textBoxTitle, textBoxAuthor, textBoxYearPublished, textBoxPrice), якщо воно не пусте, додаємо відповідний SET оператор і параметр у список.
    3. Перевірка наявності полів для оновлення: Якщо жодне з текстових полів не заповнене, виводимо повідомлення і виходимо з методу.
    4. Завершуємо запит: Додаємо умову WHERE ID = @ID до запиту, щоб оновити конкретний запис.
    5. Створюємо та виконуємо команду: Створюємо команду з параметрами і виконуємо її, потім виводимо кількість оновлених рядків.
  7. Цей підхід дозволяє гнучко оновлювати лише ті поля, які були заповнені користувачем.
  8. command.ExecuteNonQuery(): Цей метод виконує SQL-команду (запит), яка не повертає дані, а змінює дані в базі даних. Наприклад, це може бути команда на оновлення даних (UPDATE), вставку нових даних (INSERT) або видалення даних (DELETE).
  9. rowsAffected: Змінна rowsAffected присвоює результат виконання методу ExecuteNonQuery(), який представляє собою ціле число, що показує кількість рядків, які були змінені даним запитом.
     private void buttonUpdateBook_Click(object sender, EventArgs e)
    {
        // Оновлення книги за вказаним ID та перезавантаження списку книг
        UpdateBookById(Convert.ToInt32(textBoxID.Text));
        LoadBooks();
    }
    
    private void textBoxID_KeyPress(object sender, KeyPressEventArgs e)
    {
        // Валідація вводу: дозволяємо тільки цифри та керуючі символи
        if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
        {
            e.Handled = true; // Блокуємо некоректний символ
            MessageBox.Show("Будь ласка, вводьте лише цифри.", 
                          "Помилка вводу", 
                          MessageBoxButtons.OK, 
                          MessageBoxIcon.Warning);
        }
    }
    
    private void textBoxCena_KeyPress(object sender, KeyPressEventArgs e)
    {
        // Валідація вводу ціни: цифри, одна крапка та керуючі символи
        if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && e.KeyChar != '.')
        {
            e.Handled = true;
            MessageBox.Show("Будь ласка, вводьте лише цифри та одну крапку.", 
                          "Помилка вводу", 
                          MessageBoxButtons.OK, 
                          MessageBoxIcon.Warning);
        }
    
        // Перевірка на наявність більше однієї крапки
        if (e.KeyChar == '.' && (sender as TextBox).Text.Contains('.'))
        {
            e.Handled = true;
            MessageBox.Show("Дозволена лише одна крапка.", 
                          "Помилка вводу", 
                          MessageBoxButtons.OK, 
                          MessageBoxIcon.Warning);
        }
    }
    
    private void buttonSearch_Click(object sender, EventArgs e)
    {
        // Пошук книги за ID
        if (int.TryParse(textBoxID.Text, out int id)) // Конвертуємо текст у число
        {
            GetBooksById(id);
        }
        else
        {
            MessageBox.Show("Будь ласка, введіть коректний ID книги.", 
                          "Помилка вводу", 
                          MessageBoxButtons.OK, 
                          MessageBoxIcon.Warning);
        }
    }
    
    private void GetBooksById(int id)
    {
        using (OleDbConnection connection = new OleDbConnection(connectionString))
        {
            try
            {
                connection.Open();
                
                // SQL-запит для пошуку книги за ID
                string query = "SELECT * FROM Книги WHERE Код_книги = @ID";
                
                using (OleDbCommand command = new OleDbCommand(query, connection))
                {
                    // Додаємо параметр для запобігання SQL-ін'єкціям
                    command.Parameters.AddWithValue("@ID", id);
                    
                    // Виконуємо запит та заповнюємо DataTable
                    OleDbDataAdapter adapter = new OleDbDataAdapter(command);
                    DataTable dataTable = new DataTable();
                    adapter.Fill(dataTable);
                    
                    // Відображаємо результати у DataGridView
                    dataGridView2.DataSource = dataTable;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Помилка при пошуку книги: {ex.Message}", 
                              "Помилка бази даних", 
                              MessageBoxButtons.OK, 
                              MessageBoxIcon.Error);
            }
        }
    }
    
  10. Перевірка цифр і точки: В обробнику KeyPress ми додаємо додаткову перевірку для точки (e.KeyChar != '.'), щоб дозволити її введення.

    Обмеження на одну точку: Для запобігання введення більше однієї точки ми перевіряємо, чи містить поточний текстовий елемент вже точку ((sender as TextBox).Text.Contains('.')). Якщо текст вже містить точку і користувач намагається ввести ще одну, ми блокуємо цю операцію (e.Handled = true) і виводимо повідомлення про помилку.

    Цей код дозволяє користувачеві вводити лише цифри та одну точку в текстове поле, що корисно при введенні числових значень, таких як десяткові числа.

Тестування проекту

Помилка "Data type mismatch in criteria expression" виникає, коли тип даних параметра в SQL-запиті не відповідає типу даних у базі даних. У цьому випадку потрібно переконатися, що параметри у запиті UPDATE мають правильний тип даних і правильно співставлені з відповідними стовпцями в таблиці Книги.

Назад Вперед Зміст