Комментарии к 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 - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.
Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.