SQLite в Delphi: ZEOS, dbGrid и транзакции — полное руководство

SQLite — идеальная база данных для Delphi-приложений: не требует сервера, распространяется одним файлом вместе с exe, работает на любом Windows без установки. В этой статье — три способа подключить SQLite к Delphi, работа с TDBGrid, транзакции BeginTransaction/Commit и сохранение сортировки. Примеры проверены на Delphi 7, XE2 и Delphi 11.

Три способа подключить SQLite к Delphi

СпособКомпонентыDelphiПлюсыМинусы
ZEOSTZConnection, TZQuery7 — 11Бесплатно, open source, поддерживает много СУБДНужен sqlite3.dll рядом с exe
UniDACTUniConnection, TUniQuery7 — 11Стабильно, хорошая поддержка, UniDAC lite бесплатенПлатная полная версия
ODBC драйверTADOConnection + SQLite ODBC7 — 11Не нужны дополнительные компонентыНужна установка ODBC драйвера на машине пользователя

Рекомендация: для большинства проектов — ZEOS. Бесплатный, хорошо документирован, работает начиная с Delphi 7. Положите sqlite3.dll рядом с .exe и готово.

Подключение SQLite через ZEOS (ZeosLib)

Установка ZeosLib

  1. Скачайте ZeosLib с sourceforge.net/projects/zeoslib
  2. Откройте пакет для вашей версии Delphi: ZeosDbo_XE2.dpk (или аналогичный)
  3. Скомпилируйте и установите через Component → Install Package
  4. Скачайте sqlite3.dll с sqlite.org → положите рядом с .exe проекта

Настройка TZConnection на форме

Перетащите на форму компонент TZConnection (вкладка Zeos Access) и задайте свойства:

СвойствоЗначение
Driversqlite
Databaseпуть к файлу, например C:\MyApp\data.db
LibraryLocationsqlite3.dll (или оставьте пустым если dll рядом с exe)
ConnectedTrue

Через код:

ZConnection1.Driver     := 'sqlite';
ZConnection1.Database   := ExtractFilePath(Application.ExeName) + 'data.db';
ZConnection1.Connected  := True;

Относительный путь к базе данных

Всегда используйте путь относительно exe — иначе приложение сломается при переносе на другой компьютер:

// Правильно — база данных рядом с exe
ZConnection1.Database := ExtractFilePath(Application.ExeName) + 'data.db';

// Для подпапки
ZConnection1.Database := ExtractFilePath(Application.ExeName) + 'db\data.db';

Подключение через UniDAC

UniDAC (Universal Data Access Components) — коммерческий набор компонентов от Devart. Поддерживает SQLite, MySQL, PostgreSQL и другие СУБД через единый интерфейс.

// Настройка TUniConnection через код
UniConnection1.ProviderName := 'SQLite';
UniConnection1.Database     := ExtractFilePath(Application.ExeName) + 'data.db';
UniConnection1.SpecificOptions.Values['Direct'] := 'True'; // без ODBC
UniConnection1.Connect;

После подключения TUniQuery работает так же как TZQuery — привычный интерфейс для всех СУБД.

Подключение через SQLite ODBC драйвер

Используйте если не хотите устанавливать сторонние компоненты — только стандартный TADOConnection.

  1. Скачайте SQLite ODBC Driver: ch-werner.de/sqliteodbc
  2. Установите sqliteodbc.exe на компьютер пользователя
  3. Создайте DSN в «Администратор источников данных ODBC» или укажите строку подключения напрямую
// TADOConnection — строка подключения без DSN
ADOConnection1.ConnectionString :=
  'Driver={SQLite3 ODBC Driver};' +
  'Database=' + ExtractFilePath(Application.ExeName) + 'data.db' + ';' +
  'LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;';
ADOConnection1.Open;

Ограничение: ODBC драйвер нужно устанавливать на каждый компьютер пользователя. Для дистрибуции приложения ZEOS удобнее — достаточно положить sqlite3.dll в папку с exe.

Основные запросы через TZQuery

SELECT — выборка данных

// Открыть запрос через TZQuery
ZQuery1.Connection := ZConnection1;
ZQuery1.SQL.Text   := 'SELECT * FROM users ORDER BY name';
ZQuery1.Open;

// Перебрать результат
while not ZQuery1.Eof do
begin
  ShowMessage(ZQuery1.FieldByName('name').AsString);
  ZQuery1.Next;
end;

// Запрос с параметром (защита от SQL-инъекций)
ZQuery1.SQL.Text := 'SELECT * FROM users WHERE city = :city';
ZQuery1.ParamByName('city').AsString := 'Москва';
ZQuery1.Open;

INSERT — добавление записи

// Через TZQuery
ZQuery1.SQL.Text :=
  'INSERT INTO users (name, email, city) VALUES (:name, :email, :city)';
ZQuery1.ParamByName('name').AsString  := edName.Text;
ZQuery1.ParamByName('email').AsString := edEmail.Text;
ZQuery1.ParamByName('city').AsString  := edCity.Text;
ZQuery1.ExecSQL;

// Получить ID вставленной записи
LastID := ZConnection1.DbcConnection.GetLastInsertID;

UPDATE и DELETE

// UPDATE
ZQuery1.SQL.Text := 'UPDATE users SET city = :city WHERE id = :id';
ZQuery1.ParamByName('city').AsString  := 'СПб';
ZQuery1.ParamByName('id').AsInteger   := 5;
ZQuery1.ExecSQL;

// DELETE
ZQuery1.SQL.Text := 'DELETE FROM users WHERE id = :id';
ZQuery1.ParamByName('id').AsInteger := 5;
ZQuery1.ExecSQL;

Транзакции в Delphi + SQLite: BeginTransaction, Commit, Rollback

Транзакции в SQLite через ZEOS — это не просто надёжность. Массовая вставка в транзакции в 100–300 раз быстрее чем без неё, потому что SQLite не делает fsync на каждую операцию.

Через ZEOS (TZConnection)

// Начало транзакции
ZConnection1.StartTransaction;
try
  ZQuery1.SQL.Text := 'INSERT INTO log (message) VALUES (:msg)';
  for i := 1 to 10000 do
  begin
    ZQuery1.ParamByName('msg').AsString := 'Запись ' + IntToStr(i);
    ZQuery1.ExecSQL;
  end;
  ZConnection1.Commit;   // Зафиксировать
except
  ZConnection1.Rollback; // Откатить при ошибке
  raise;
end;

Через прямой SQL (работает в любом компоненте)

// Работает через TZQuery, TADOQuery, TUniQuery — в любом компоненте
ZQuery1.SQL.Text := 'BEGIN TRANSACTION';
ZQuery1.ExecSQL;
try
  // ... ваши запросы ...
  ZQuery1.SQL.Text := 'COMMIT';
  ZQuery1.ExecSQL;
except
  ZQuery1.SQL.Text := 'ROLLBACK';
  ZQuery1.ExecSQL;
  raise;
end;

zeos delphi sqlite commit — частая ошибка

Если при вызове ZConnection1.Commit получаете ошибку «No active transaction» — значит ZEOS открыл транзакцию автоматически (AutoCommit = True). Решение:

// Отключить AutoCommit перед началом ручной транзакции
ZConnection1.AutoCommit := False;
ZConnection1.StartTransaction;
// ... запросы ...
ZConnection1.Commit;
ZConnection1.AutoCommit := True; // вернуть если нужно

TDBGrid и SQLite: отображение таблицы

TDBGrid работает с SQLite через стандартную связку: TZConnection → TZQuery → TDataSource → TDBGrid.

Настройка на форме

  1. Перетащите на форму: TZConnection, TZQuery, TDataSource, TDBGrid
  2. ZQuery1.Connection := ZConnection1
  3. DataSource1.DataSet := ZQuery1
  4. DBGrid1.DataSource := DataSource1
  5. ZQuery1.SQL.Text := ‘SELECT * FROM users’
  6. ZQuery1.Open

Настройка через код

procedure TForm1.FormCreate(Sender: TObject);
begin
  ZConnection1.Driver   := 'sqlite';
  ZConnection1.Database := ExtractFilePath(Application.ExeName) + 'data.db';
  ZConnection1.Connected := True;

  ZQuery1.Connection := ZConnection1;
  ZQuery1.SQL.Text   := 'SELECT id, name, city, email FROM users ORDER BY name';
  ZQuery1.Open;

  DataSource1.DataSet := ZQuery1;
  DBGrid1.DataSource  := DataSource1;
end;

Настройка колонок DBGrid

// Задать заголовки колонок программно
DBGrid1.Columns[0].Title.Caption := 'ID';
DBGrid1.Columns[0].Width         := 40;
DBGrid1.Columns[1].Title.Caption := 'Имя';
DBGrid1.Columns[1].Width         := 150;
DBGrid1.Columns[2].Title.Caption := 'Город';
DBGrid1.Columns[2].Width         := 120;

DBGrid SQLite: сохранить сортировку при нажатии на заголовок

TDBGrid не умеет сортировать по клику на заголовок «из коробки». Реализуем через событие OnTitleClick — при клике на заголовок колонки перезапрашиваем данные с нужным ORDER BY.

// В секции private формы объявить переменные
private
  FSortField: string;
  FSortAsc:   Boolean;
// В FormCreate инициализировать
procedure TForm1.FormCreate(Sender: TObject);
begin
  FSortField := 'name';  // сортировка по умолчанию
  FSortAsc   := True;
  LoadData;
end;

procedure TForm1.LoadData;
var
  Direction: string;
begin
  if FSortAsc then Direction := 'ASC' else Direction := 'DESC';
  ZQuery1.Close;
  ZQuery1.SQL.Text := Format(
    'SELECT id, name, city, email FROM users ORDER BY %s %s',
    [FSortField, Direction]
  );
  ZQuery1.Open;
end;
// Обработчик клика по заголовку колонки
procedure TForm1.DBGrid1TitleClick(Column: TColumn);
begin
  if FSortField = Column.FieldName then
    FSortAsc := not FSortAsc  // переключить направление
  else
  begin
    FSortField := Column.FieldName;
    FSortAsc   := True;
  end;
  LoadData;
end;

Чтобы сохранить сортировку между сессиями — запишите FSortField и FSortAsc в реестр или ini-файл при закрытии формы.

// Сохранение в ini-файл
procedure TForm1.FormDestroy(Sender: TObject);
var
  Ini: TIniFile;
begin
  Ini := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'settings.ini');
  try
    Ini.WriteString('Grid', 'SortField', FSortField);
    Ini.WriteBool  ('Grid', 'SortAsc',   FSortAsc);
  finally
    Ini.Free;
  end;
end;

// Загрузка при старте
procedure TForm1.FormCreate(Sender: TObject);
var
  Ini: TIniFile;
begin
  Ini := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'settings.ini');
  try
    FSortField := Ini.ReadString('Grid', 'SortField', 'name');
    FSortAsc   := Ini.ReadBool  ('Grid', 'SortAsc',   True);
  finally
    Ini.Free;
  end;
  ZConnection1.Connected := True;
  LoadData;
end;

Создание базы данных и таблиц из кода Delphi

SQLite создаёт файл базы автоматически при первом подключении. Таблицы создайте при старте приложения:

procedure TForm1.InitDatabase;
begin
  ZConnection1.Driver   := 'sqlite';
  ZConnection1.Database := ExtractFilePath(Application.ExeName) + 'app.db';
  ZConnection1.Connected := True;

  // Создать таблицы если не существуют
  ZQuery1.Connection := ZConnection1;

  ZQuery1.SQL.Text :=
    'CREATE TABLE IF NOT EXISTS users (' +
    '  id         INTEGER PRIMARY KEY AUTOINCREMENT,' +
    '  name       TEXT    NOT NULL,' +
    '  email      TEXT    UNIQUE,' +
    '  city       TEXT,' +
    '  created_at TEXT    DEFAULT (datetime(''now'', ''localtime''))' +
    ')';
  ZQuery1.ExecSQL;

  ZQuery1.SQL.Text :=
    'CREATE INDEX IF NOT EXISTS idx_users_city ON users(city)';
  ZQuery1.ExecSQL;
end;

Обратите внимание: в Delphi строках одинарные кавычки удваиваются: ''now'' = SQL-строка 'now'.

Миграция с Paradox и Access на SQLite

Если ваше приложение использует Paradox (.db таблицы BDE) или Access (.mdb), SQLite — логичная замена: нет зависимости от BDE/JET, работает на 64-bit Windows без установки.

Соответствие типов данных

Paradox / AccessSQLite типDelphi тип поля
Short, Integer, LongINTEGERTIntegerField
Number, Float, DoubleREALTFloatField
Alpha, TextTEXTTStringField
Date, Time, DateTimeTEXT (ISO: YYYY-MM-DD)TDateTimeField
Logical, BooleanINTEGER (0/1)TBooleanField
Memo, Long TextTEXTTMemoField
Binary, BlobBLOBTBlobField

Перенос данных из Paradox в SQLite

// Пример переноса: читаем из TTable (BDE/Paradox), пишем в ZQuery (SQLite)
procedure MigrateUsers;
begin
  // Открыть источник (Paradox)
  TableSource.DatabaseName := 'C:\OldApp\data';
  TableSource.TableName    := 'USERS.DB';
  TableSource.Open;

  // Подготовить INSERT в SQLite
  ZQueryDest.SQL.Text :=
    'INSERT INTO users (name, email, city) VALUES (:name, :email, :city)';

  ZConnection1.StartTransaction;
  try
    while not TableSource.Eof do
    begin
      ZQueryDest.ParamByName('name').AsString  := TableSource.FieldByName('NAME').AsString;
      ZQueryDest.ParamByName('email').AsString := TableSource.FieldByName('EMAIL').AsString;
      ZQueryDest.ParamByName('city').AsString  := TableSource.FieldByName('CITY').AsString;
      ZQueryDest.ExecSQL;
      TableSource.Next;
    end;
    ZConnection1.Commit;
    ShowMessage('Перенесено записей: ' + IntToStr(TableSource.RecordCount));
  except
    ZConnection1.Rollback;
    raise;
  end;

  TableSource.Close;
end;

Оптимизация SQLite в Delphi-приложениях

Несколько PRAGMA-настроек, которые стоит включать сразу после подключения:

procedure TForm1.OptimizeDB;
begin
  // Режим WAL — параллельное чтение и запись
  ZQuery1.SQL.Text := 'PRAGMA journal_mode = WAL';
  ZQuery1.ExecSQL;

  // Кеш страниц: 32 МБ (по умолчанию ~2 МБ)
  ZQuery1.SQL.Text := 'PRAGMA cache_size = -32000';
  ZQuery1.ExecSQL;

  // Временные таблицы в памяти
  ZQuery1.SQL.Text := 'PRAGMA temp_store = MEMORY';
  ZQuery1.ExecSQL;

  // Баланс скорость / надёжность записи
  ZQuery1.SQL.Text := 'PRAGMA synchronous = NORMAL';
  ZQuery1.ExecSQL;
end;

Вызовите OptimizeDB сразу после ZConnection1.Connected := True.

Дистрибуция: что положить рядом с exe

Для работы Delphi-приложения с SQLite через ZEOS на компьютере пользователя нужно:

ФайлОткуда взятьОбязателен
YourApp.exeВаш проект
sqlite3.dllsqlite.org/download → Precompiled Binaries for Windows✅ для ZEOS
data.dbСоздаётся автоматически при первом запуске

Скачивайте sqlite3.dll с sqlite.org — выбирайте разрядность под вашу сборку: x86 для 32-bit приложений, x64 для 64-bit.

Для UniDAC: прямое подключение (Direct=True) также требует sqlite3.dll. Режим через ODBC требует установки ODBC-драйвера на каждом компьютере пользователя — менее удобно для дистрибуции.

Изучите SQLite подробнее

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x