Комментарии к SQLite


По заметке, которую я написал по работе над новым проектом, программой для создания каталогов, у заказчика, которого я одновременно немного консультирую по программированию, возник ряд вопросов. Публикую ответы в виде изложения и тут – вдруг кому-то тоже окажется полезным. Буду говорить максимально просто, некоторые вещи могут показаться профессиональным программистам наивными, но я старался все объяснить максимально доходчиво. При обучении программированию на первоначальном этапе важны не подробности, а общее понимание.

Мы используем в нашем проекте sqllite – чтобы не устанавливать/загружать сервера sql. Для этого мы и добавляем в проект библиотеки – чтобы пользоваться функциями работы с базами данных. После добавления библиотек (dll) в проект надо еще подключить пространство имен.

using System.IO;
Это подключаем устройства ввода/вывода. Точнее, с помощью него мы можем читать файлы, работать с файловой системой, байтами необработанных данных и так далее.

using System.Data;
Нам нужен для работы с отображением данных в таблице (датагриде) - это как бы провайдер между данными и визуальным представлением. Все, теперь мы в полной мере можем работать с базами. В первых двух строках мы создавали файл базы

dbFileName = textBox1.Text+".sqlite";
if (!File.Exists(dbFileName)) SQLiteConnection.CreateFile(dbFileName);
Сейчас дам немного общей теории.

В C# как и других языках программирования используются переменные. Причем переменные типизированные. Например, вот эта переменная dbFileName - это тип String – мы её вводили в начале кода?

textBox1.Text - здесь мы берем текст и текстбокса первого и добавляем расширение: ".sqlite"; Далее в строке if (!File.Exists(dbFileName)) SQLiteConnection.CreateFile(dbFileName); мы сначала проверяем существование файла, и если его нет, то создаем. Восклицательный знак означает, что выражение в скобках должно быть false, чтобы выполнилось условие.

Вот, например, для этого мы и использовали using System.IO - чтобы можно было задействовать метод File.Exists. Дальше, вот этим кодом мы создали таблицу

try
            {
m_dbConn = new SQLiteConnection("Data Source=" + dbFileName + ";Version=3;");
m_dbConn.Open();
m_sqlCmd.Connection = m_dbConn;

m_sqlCmd.CommandText = "CREATE TABLE IF NOT EXISTS Catalog (id INTEGER PRIMARY KEY AUTOINCREMENT, product TEXT, characteristics TEXT)";
m_sqlCmd.ExecuteNonQuery();
MessageBox.Show("Таблица успешно создана!");
            }
            catch (SQLiteException ex)
            {
                MessageBox.Show("Ошибка: " + ex.Message);
            }
Во-первых, обратите внимание, что весь отрывок кода заключен в конструкцию try {} catch{}. Это специальная конструкция, предназначенная для отлавливания ошибок. То есть, если что-то пойдет не так - например, нет файла базы - то программа продолжит свою работу, просто выдав ошибку не прекратит полностью.

В программировании данная конструкция встречается часто. Например, в создании калькулятора, отлавливаем ошибку деления на ноль, в чтении файла с диска и тд. В данном случае программа просто выдаст окно с ошибкой:

MessageBox.Show("Ошибка: " + ex.Message);
Это одна конструкция из двух операторов

try{  тут что-то опасное делаем }
catch  { тут делаем что-то если исключение вылезло }
Здесь создаем строку подключения.

m_dbConn = new SQLiteConnection("Data Source=" + dbFileName + ";Version=3;");
Источник - файл, версия - 3

m_dbConn.Open();
Здесь открываем подключение

m_sqlCmd.Connection = m_dbConn;
Здесь подключаемся

m_sqlCmd.CommandText = "CREATE TABLE IF NOT EXISTS Catalog (id INTEGER PRIMARY KEY AUTOINCREMENT, product TEXT, characteristics TEXT)";
Это строка с параметрами, с какими будет создаваться таблица. Условие (IF NOT EXISTS) название (Catalog) ну и столбцы. Типы могут быть и другими кроме integer (целые) и text. есть ограниченный тип text – varchar. Есть типы хранения дат. Есть для бинарных данных - в ним можно хранить, к примеру, картинки

m_sqlCmd.ExecuteNonQuery();
В этой строке мы выполняем запрос к базе. Execute - выполняем NonQuery - запрос без ответа. То есть в результате выполнения нам не нужен ответ. Есть другие типы запросов, например, выборка данных - там ответ нужен. В конце не забываем закрыть соединение:

m_dbConn.Close();
Это не просто прихоть, в некоторых случаях может выдать ошибку, если попытаемся открыть уже открытое.

Самое главное в создании базы - это продумать структуру таблиц. Например, в одной ид товара + его характеристики + ид производителя. А в другой ид производителя + описание производителя. Сложная фильтрация - вот на этом этапе все и прорабатывается. У товара должно быть уникальное ид (необязательно цифровое, просто так удобнее) и сколько угодно других характеристик, номер, артикул и т.д

Дальше вы уж сами уже можете понять, в какой строке мы вставляем запись в таблицу:

m_sqlCmd.CommandText = "INSERT INTO Catalog ('product', 'characteristics') values ('" + textBox2.Text + "' , '" + textBox3.Text + "')";
m_sqlCmd.ExecuteNonQuery();
Думаю, ничего сложного нет. Да, замечание небольшое. textBox2.Text - это мы получаем значение, введенное пользователем. Но также мы его и можем сами в коде назначить. Например, textBox2.Text = "товар3"; - в любом месте кода.

Это последнее может быть нужно для вывода любой информации на экран, которая возникает в процессе работы программы. Необязательно же использовать окно с сообщением каждый раз.

Можно сделать не textbox, а к примеру label и менять его значение также. Например, каждую минуту - сделать часы. Нам это пригодится, когда мы будем делать карточки товара (каталог) - там у нас будет одна форма, но текст на элементах будет подставляться в зависимости от полученного из базы. Чтобы сделать неизменяемым, свойство тексбокса enabled измени на false. Но вообще, для неизменяемых надписей лучше пользоваться метками - компонент label.

Далее. Вот этот кусок кода

sqlQuery = "SELECT * FROM Catalog";
SQLiteDataAdapter adapter = new SQLiteDataAdapter(sqlQuery, m_dbConn);
adapter.Fill(dTable);

                if (dTable.Rows.Count > 0)
                {
                    dgvViewer.Rows.Clear();

                    for (int i = 0; i < dTable.Rows.Count; i++)
                        dgvViewer.Rows.Add(dTable.Rows[i].ItemArray);
                }
Первая строка - это запрос к нашей базе - выбрать все строки из таблицы. Это тяжелый запрос, чаще всего делают более легкий, например

sqlQuery = "SELECT * FROM Catalog WHERE id = '1'";
Это значит, что мы выбираем из таблицы catalog все данные строки с id = 1. Если нам не нужны все данные, то делаем так

sqlQuery = "SELECT product FROM Catalog WHERE id = '1'";
Но здесь мы берем именно все данные, так как сразу их вставляем в наш датагрид

Вот эта конструкция

for (int i = 0; i < dTable.Rows.Count; i++)
называется цикл. Берем некоторую переменную, приравниваем её к нулю и проходим до значения dTable.Rows прибавляя по одному. i++ это тоже самое, что и i = i + 1 - сокращенная запись, очень часто используется в программировании.

dgvViewer.Rows.Add(dTable.Rows[i].ItemArray);
тут тоже ничего сложного в строку датагрида вставляем строку таблицы.

Если у вас есть какие-то вопросы, или же вам требуется консультация по программированию, помощь онлайн, то вы можете написать мне. Помогу недорого в самых разных задачах по программированию.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, SQLite, си шарп, visual stidio, примеры




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.



Блог читающего программиста
Переход с инстаграма на сайт, ошибки https и перенос на другой хостинг
Введение в скрипты Postman