Рейтинг:  5 / 5

Звезда активнаЗвезда активнаЗвезда активнаЗвезда активнаЗвезда активна
 

Как видно из заголовка в данной статье пойдет разговор о работе с базами данных при помощи Ide Lazarus.  Базы данных занимают важную роль в современном мире,  их используют для создания большинства сайтов, информационных систем, различных программ. В мире насчитывается огромное количество СУБД (Система управления базами данных), как коммерческих MsSql, Orcle, Interbase так и бесплатных вроде MySQl, PostgreSQL, Firebird, Sqlite. Lazarus же позволяет работать с большинством из них, для этого в среду можно установить компоненты для работы с соответствующими СУБД. Мы же рассмотрим общие способы работы с базами данных. В основе большинства баз данных лежит язык SQL (язык структурированных запросов), который позволяет получать о обрабатывать наборы данных.  По поводу синтаксиса данного языка можно почитать на википедии либо на соответствующих форумах. Мы же будет рассматривать непосредственную работу с данными.

 

Для начинающих работать в Lazarus в качестве первого опыта вполне подойдет стандартный набор компонентов с  вкладки SQLdb, данная вкладка содержит набор для работы с различными СУБД.

sqldb Состав вкладки SQLdb.

tsqlquery  TSQLQuery Компонент для получения и изменения данных 
tsqltransaction  TSQLTransaction  Компонент для работы с транзакциями
tsqlscript TSQLScript Компонент для работы с большим количеством Sql кода
tsqlconnector TSQLConnector Компонент для установления подключения к различным базам данных
TMSSQLConnection Компонент для подключения к СУБД MSSql (Microsoft SQL Server)
tsybaseconnection TSybaseConnection Компонент для подключения к СУБД Sybase (Sybase SQL Server)
tpqconnection TPQConnection Компонент для подключения к СУБД PostgreSQL
tpqteventmonitor TPQTEventMonitor Компонент для взаимодействия с событиями  в  PostgreSQL
toracleconnection TOracleConnection Компонент для работы с СУБД Oracle
TODBCConnection Компонент для доступа к данными посредством драйверов ODBC
tmysql40connection TMySQL40Connection  Компонент для подключения к СУБД MySql версии 4.0
tmysql41connection TMySQL41Connection  Компонент для подключения к СУБД MySql версии 4.1
tmysql50connection TMySQL50Connection  Компонент для подключения к СУБД MySql версии 5.0
tmysql51connection TMySQL51Connection  Компонент для подключения к СУБД MySql версии 5.1
tmysql55connection  TMySQL55Connection  Компонент для подключения к СУБД MySql версии 5.5
tmysql56connection TMySQL56Connection  Компонент для подключения к СУБД MySql версии 5.6
tsqlite3connection TSQLite3Connection  Компонент для подключения к СУБД SQLite
tibconnection TIBConnection  Компонент для подключения к СУБД Firebird, Interbase
tfbadmin TFBAdmin  Компонент для управления сервером Firebird
tfbeventmonitor TFBEventMonitor  Компонент для работы с событиями Firebird, Interbase
tsqldblibraryloader TSQLDBLibraryLoader  Компонент для загрузки библиотеки доступа к  данным

 

Так же для работы потребуется компонент  TDataSource tdatasource с вкладки Data Access, он является прослойкой между компонентами для доступа к данным и компонентами для отображения данных.

Доступ к данным.

Для подключения к какой либо СУБД на форму или датамодуль следует  разместить требуемый  компонент. Все зависит от требуемой СУБД.  Я выбрал SQLite и соответственно добавил на форму TSQLite3Connection.  Он позволит настроить подключение к требуемой базе данных. Так же следует добавить на форму компонент TSQLTransaction. Он обеспечивает целостность работы с данными. О нем будет позже более подробнее.

Поскольку SQLite это локальная СУБД,  то не требуется указывать такие параметры соединения как сервер, порт, пользователь, пароль, достаточно указать только путь к файлу базы и кодировку для работы, а также указать компонент для транзакции.

Сделать это можно примерно так.

 

procedure TForm1.Button1Click(Sender: TObject);
begin
  SQLite3Connection1.DatabaseName := 'c:\test\test.db3'; // указывает путь к базе
  SQLite3Connection1.CharSet := 'UTF8'; // указываем рабочую кодировку
  SQLite3Connection1.Transaction := SQLTransaction1; // указываем менеджер транзакций
  try  // пробуем подключится к базе
    SQLite3Connection1.Open;
    SQLTransaction1.Active := True;
  except   // если не удалось то выводим сообщение о ошибке
    ShowMessage('Ошибка подключения к базе!');
  end;
end;

 Для того что бы программа заработала необходимо в папку с проектом поместить библиотеку sqlite3.dll, скачать последнюю версию которой можно тут. Для остальных СУБД тоже потребуются соответствующие библиотеки.

 Что бы получить данные из базы на форму помещается компонент SQLQuery1, у него в качестве database указывается  компонент SQLite3Connection1, а в качестве параметра transaction компонент SQLTransaction1. 

Затем  вписать в свойство SQL соответствующий запрос для выборки данных и выполнить процедуру Open. Если требуется добавить изменить или удалить данные то следует сделать ExecSQL. 

Пример кода.

procedure TForm1.Button2Click(Sender: TObject);
begin
  SQLQuery1.Close;
  SQLQuery1.SQL.Text:='select * from table';
  SQLQuery1.Open;
end;

 После этого мы получим набор данных,  если точнее таблицу.  Для работы с ней компонент TSQLQuery содержит базовый набор функций и свойств. 

Для навигации по набору данных используются следующие методы.

 

First Перейти на самую первую запись
Last Перейти на самую последнюю запись
Prior Перейти на запись назад
Next Перейти на запись вперед

Данные методы позволяют передвигаться по строкам таблицы.

Допусти нам надо пройтись по всем строкам таблицы и скопировать определенное значение,  самый простой способ будет таким.

  SQLQuery1.Open; // открываем данные
  SQLQuery1.First; // становимся на первую запись
  while not SQLQuery1.EOF do // цикл пока не конец набора данных
  begin
    // обрабатываем данные
    SQLQuery1.Next; // переходим на следующую запись
  end;
  SQLQuery1.Close; // закрываем данные 

Так  же для навигации по данным можно использовать визуальный компонент TDBNavigator. 

Для отображения данных из базы используются компоненты из вкладки Data Controls, они созданы на базе обычных визуальных компонентов, но предназначены для отображения данных различных типов.

Что бы отобразить полученные данные на форму размещается компонент DataSource1 и визуальный компонент DBGrid1. У компонента  DataSource1 свойству DataSet присваивается компонент  SQLQuery1, а у компонента  DBGrid1 выставляется свойство DataSource равным  DataSource1. Теперь если сделать SQLQuery1.Open то в таблице отобразятся данные из базы.

sqldb

 

 Добавление данных

Добавлять данные в таблицу можно двумя способами. Один через открытый набор данных. Второй через выполнение специального sql запроса INSERT.  Рассмотрим оба способа.

Добавление данных через открытый набор данных.

Для манипулирования с данными используются следующие команды.

Append Открывает процедуру добавления записи в конец набора данных
Insert Открывает процедуру добавления записи в текущее место набора данных
Edit Открывает процедуру редактирование текущей записи
Post Записывает данные
Delete Удаляет выбранную запись
Cancel Отменяет процедуру работы с данными
Refresh Обновляет  набор данных

Эти команды использует большинство компонентов для работы с данными. 

 Пример добавления новой записи через набор данных.

procedure TForm1.Button3Click(Sender: TObject);
begin
  SQLQuery1.Append; // открываем процедуру добавления данных
  SQLQuery1.Fields.FieldByName('pre').AsString:='00'; // присваиваем записи текстовое значение
  SQLQuery1.Fields.FieldByName('code').AsString:='000';
  Sqlquery1.Post; // записываем данные
  sqlquery1.ApplyUpdates;// отправляем изменения в базу
  SQLTransaction1.Commit; // подтверждаем изменения в базе
end;

 Может показаться что слишком много команд надо выполнить что бы данные занести в базу. Но это необходимо выполнять только для данных компонентов, есть более человеческие компоненты, где хватает только одного Post.

 

Пример добавления данных через sql запрос.

procedure TForm1.Button4Click(Sender: TObject);
begin
  SQLQuery1.Close;  // выключаем компонент
  SQLQuery1.SQL.Text := 'insert into usl(pre,code) values(:p,:u);';  // добавляем sql запрос для добавления данных
  SQLQuery1.ParamByName('p').AsString := '00';// присваиваем записи текстовое значение
  SQLQuery1.ParamByName('u').AsString := '111';
  SQLQuery1.ExecSQL; // выполняем запрос
  SQLTransaction1.Commit; //подтверждаем изменения в базе
end;

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

Изменение данных.

Изменить данные в базе можно несколькими способами. Рассмотрим два способа изменения данных при помощи компонентов Sqldb.

Первый способ будет через открытый набор данных.

procedure TForm1.Button5Click(Sender: TObject);
begin
  SQLQuery1.edit; // открываем процедуру добавления данных
  SQLQuery1.Fields.FieldByName('pre').AsString := '00';
  // присваиваем записи текстовое значение
  SQLQuery1.Fields.FieldByName('code').AsString := '000';
  Sqlquery1.Post; // записываем данные
  sqlquery1.ApplyUpdates;// отправляем изменения в базу
  SQLTransaction1.Commit; // подтверждаем изменения в базе
end;

 Достаточно встать на требуемую запись и открыть её через процедуру Edit 

procedure TForm1.Button5Click(Sender: TObject);
begin
  SQLQuery1.Edit; // открываем процедуру добавления данных
  SQLQuery1.Fields.FieldByName('pre').AsString := '00';
  // присваиваем записи текстовое значение
  SQLQuery1.Fields.FieldByName('code').AsString := '000';
  Sqlquery1.Post; // записываем данные
  sqlquery1.ApplyUpdates;// отправляем изменения в базу
  SQLTransaction1.Commit; // подтверждаем изменения в базе
end;

Так же данные можно редактировать через sql запрос UPDATE 

procedure TForm1.Button6Click(Sender: TObject);
begin
  SQLQuery1.Close;  // выключаем компонент
  SQLQuery1.SQL.Text := 'update table1 set name =:nm, adres=:ad where id=:id;';
  // добавляем sql запрос для добавления данных
  SQLQuery1.ParamByName('nm').AsString := 'Иванов И.И.';// присваиваем записи текстовое значение
  SQLQuery1.ParamByName('ad').AsString := 'Москва, Кучерявая 6';
  SQLQuery1.ParamByName('id').AsString := '2016';
  SQLQuery1.ExecSQL; // выполняем запрос
  SQLTransaction1.Commit; //подтверждаем изменения в базе
end; 

 

 Удаление данных

 Удалить данные из базы не сложно, главное удалить именно те данные, а не те которые были нужны. Зачастую от этого спасают транзакции и бекапы. Но не всегда. Рассмотрим  так же два способа удаления данных.

Удаление из набора данных. Просто становимся на требуемую запись и выполняем следующий код.

procedure TForm1.Button7Click(Sender: TObject);
begin
  SQLQuery1.Delete; // удаляем запись
end;

 Также удалить данные можно через sql запрос DELETE, делается это следующим образом.

procedure TForm1.Button8Click(Sender: TObject);
begin
  SQLQuery1.Close;  // закрываем компонент
  SQLQuery1.SQL.Text:='delete from table1 where id=:id'; // запрос на удаление данных
  SQLQuery1.ParamByName('id').AsString:='2015'; //указываем требуемый параметр
  SQLQuery1.ExecSQL; // выполняем запрос
  SQLTransaction1.Commit; //подтверждаем изменения в базе
end;

 При удаление данных через запрос нужно точно знать какие данные удалять. Если сделать так.

DELETE from table1

 То удаляться все данные из таблицы table1. Поэтому требуется точно указывать какие данные удалять.

 

Поиск данных.

Поиск данные является одной из необходимых вещей при работе с базами данных. Существует несколько способов осуществления данной операции. Не будем рассматривать все. Остановимся на самых простых.

Первым способом будет поиск в выбранном наборе данных. Он осуществляется по конкретному столбцу или столбцам данных. Выглядит это так.

SQLQuery1.Locate('name','нужное значение',[loCaseInsensitive, loPartialKey]);
//'name' - название нужного нам столбца 
//'нужное значение' - то что ищем
//loCaseInsensitive - игнорируем регистр записи
//loPartialKey - частичное совпадение

 При использование данной записи маркер выбранной записи переместиться на найденную запись, если искомых данных не будет обнаружено то маркер переместиться на последнюю запись.

Так же можно сделать выборку данных с условием отбора SELECT ... WHERE делается это так.

procedure TForm1.Button10Click(Sender: TObject);
begin
  SQLQuery1.Close;// закрываем датасет
  SQLQuery1.SQL.Text := 'select * from table1 where name = :nm'; // добавляем наш запрос
  SQLQuery1.ParamByName('nm').AsString:='иван';// присваиваем требуемый параметр
  SQLQuery1.Open;// открываем запрос
end; 

 Данный запрос применяется для поиска по точным данным. Если же требуется найти все похожие данные  то тут применяется функция sql  LIKE, позволяет задать примерный поиск значения в строках данных для конкретного столбца.   Синтаксис данной функции такой

name LIKE 'И%'  -- выведет все имена начинающиеся на И
name LIKE 'И___' -- выведет все имена содержащие 3 любых символа после И

 

Пример использования функции из кода.

procedure TForm1.Button11Click(Sender: TObject);
begin
  SQLQuery1.Close;  // закрываем компонент
  SQLQuery1.SQL.Text := 'select * from table1 where name like :nm';  // запрос на поиск данных
  SQLQuery1.ParamByName('nm').AsString := '%'+'и'+'%'; //правильное заполнение
  SQLQuery1.Open; // выполняем запрос
end;

 Данный запрос выведет все имена содержащие букву и. 

 Есть небольшая проблема у SQLite. В данной СУБД оператор LIKE поддерживаться полностью только для латиницы, для кириллицы он тоже работает но только с соблюдением регистра букв. Что бы избежать данной проблемы требуется либо использовать библиотеку sqlite3.dll с поддержкой ICU, либо использовать свою функцию LIKE. 

 Транзакции

Транзацкии в базах данных обеспечивают целостность и защищенность данных. Они позволяют изменить данные в базе либо вернуть предыдущее состояние данных в пределах транзакции. Имеется различный уровень изоляции данных при работе транзакций, это зависит от используемой СУБД.

Пример работы с транзакциями из кода.

procedure TForm1.Button12Click(Sender: TObject);
begin
  SQLTransaction1.StartTransaction;
  try
  // обрабатываем данные
    SQLTransaction1.Commit; // если все хорошо вносим изменения в базу
  except
  //в случае ошибки обработки вернем данные в исходное состояние
  SQLTransaction1.Rollback;
  end;
end;

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

Вот так примерно можно работать с базами данных из Lazarus при использование компонентов SQLdb. Данная статья не претендует на звание самого умного документа, а просто показывает общие методы работы с базами данных.

Предыдущая статья - Уменьшение размера исполняемого файла в Lazarus

 

Комментарии   
0 #13 cialis 27.04.2019 01:30
Hi there would you mind sharing which blog platform you're working with?
I'm looking to start my own blog soon but I'm having a difficult time selecting between BlogEngine/Word press/B2evoluti on and Drupal.
The reason I ask is because your layout seems
different then most blogs and I'm looking for something unique.

P.S My apologies for being off-topic but I had to ask!


my blog: cialis: [censored]://co stofcial.com
Цитировать
+3 #12 Антон 01.10.2017 11:34
Чувак Спасибо, все описано понятно и просто, но
мне тревожат душу следующие вопросы:
*как работать с несколькими таблицами?
*как использовать компонент DBLookupComboBox?
*возможно ли выводить несколько связанных таблиц?
Увы ответов в статье я не нашел :cry:
Цитировать
-1 #11 Sasha 15.10.2016 22:41
Цитирую Алексей:
В статье ошибка, запросы с поиском, содержащим LIKE, должны выглядеть иначе, двойные кавычки парсером параметров не парсятся, проценты тоже.
Правильно будет так:
SQLQuery1.SQL.Text := 'select * from table1 where name like :nm'; // запрос на поиск данных
SQLQuery1.ParamByName('nm').AsString := '%и%';
Кавычки не нужны, потому как это автоматом делает AsString, а проценты не парсятся, поэтому уходят в сам параметр, уж не знаю, баг это или фича.
Полдня вчера на этом потерял :(

Да есть такое дело, просто руки не доходят поправить статью, сломалась оповещалка о новых комментариях.
Цитировать
+2 #10 Алексей 06.10.2016 14:39
В статье ошибка, запросы с поиском, содержащим LIKE, должны выглядеть иначе, двойные кавычки парсером параметров не парсятся, проценты тоже.
Правильно будет так:
SQLQuery1.SQL.Text := 'select * from table1 where name like :nm'; // запрос на поиск данных
SQLQuery1.Param ByName('nm').As String := '%и%';
Кавычки не нужны, потому как это автоматом делает AsString, а проценты не парсятся, поэтому уходят в сам параметр, уж не знаю, баг это или фича.
Полдня вчера на этом потерял :(
Цитировать
+2 #9 Electron 03.09.2016 23:08
Спасибо за статью! У меня возник один вопрос - как вывести список таблиц в ListBox по SQL-запросу "SELECT * FROM sqlite_master WHERE type = "table" ORDER BY name"?
Цитировать
+1 #8 mrkaban 01.09.2016 14:11
Спасибо большое, разобрались, я взял sql дамп из mysql и пытался его использовать.

Создал базу через SQLiteStudio и всё заработало!
Цитировать
-1 #7 mrkaban 01.09.2016 12:13
Цитирую Sasha:
SQLQuery и SQLDataSet это по сути одно и тоже, что бы данные отобрадать надо SQLQuery и datasource , у datasource необходимо указать dataset

это я не то название случайно скопировал, я имел введу связать SQLQuery1 и DataSource1.

А нужно ли в SQLQuery1 указывать что-то в пункт DataSource?
Цитировать
0 #6 Sasha 01.09.2016 10:32
SQLQuery и SQLDataSet это по сути одно и тоже, что бы данные отобрадать надо SQLQuery и datasource , у datasource необходимо указать dataset
Цитировать
0 #5 mrkaban 01.09.2016 10:08
Не могу разобраться, вылетает ошибка, когда пытаюсь связать SQLQuery и SQLDataSet, в друг друге указываю их, тогда сразу прям в лазарусе вылетает ошибка "SQLQuery1: Circular datasource references are not allowed".

А еще, почему-то у вас не работают уведомления о новых комментариях
Цитировать
0 #4 Sasha 31.08.2016 08:17
Цитирую mrkaban:
а есть ли еще у вас статьи посвященные данной теме?

День добрый.
Спасибо за отзыв, вижу что это помогает людям осваивать программировани е. Статей пока других нет, поскольку нет времени свободного сайтом заняться, пойду в отпуск дополню сайт статьями по работе с sqlite, mysql, postgresql, firebird
Цитировать
Добавить комментарий