- Знакомство с принципами работы с базой данных в MQL5
- Основы SQL
- Структура (схема) таблиц: типы данных и ограничения
- Интеграция ООП (MQL5) и SQL: концепция ORM
- Создание, открытие и закрытие базы данных
- Выполнение запросов без привязки к данным MQL5
- Проверка существования таблицы в базе данных
- Подготовка запросов с привязкой: DatabasePrepare
- Удаление и сброс подготовленных запросов
- Привязка данных к параметрам запроса:DatabaseBind/Array
- Выполнение подготовленных запросов: DatabaseRead/Bind
- Раздельное чтение полей: DatabaseColumn-функции
- Примеры CRUD-операций в SQLite через объекты ORM
- Транзакции
- Импорт и экспорт таблицы базы данных
- Печать таблиц и SQL-запросов в журнал
- Пример поиска торговой стратегии средствами SQLite
Удаление и сброс подготовленных запросов
Поскольку подготовленные запросы могут выполняться многократно, в цикле для различных значений параметров, на каждой итерации требуется сбрасывать запрос в начальное состояние. Для этого предназначена функция DatabaseReset. Но её не имеет смысла вызывать, если подготовленный запрос выполняется однократно.
bool DatabaseReset(int request)
Функция приводит внутренние откомпилированные структуры запроса в начальное состояние, как после вызова DatabasePrepare. Однако DatabaseReset не компилирует запрос заново и потому выполняется очень быстро.
Также важно, что функция не сбрасывает уже установленные привязки данных в запросе, если они были сделаны. Таким образом, при необходимости можно менять значение только одного или малого числа параметров — достаточно после вызова DatabaseReset вызывать DatabaseBind-функции только для изменившихся параметров.
На момент написания книги MQL5 API не предоставляло функцию для сброса привязки данных, аналог функции sqlite_clear_bindings в стандартном дистрибутиве SQLite.
В параметре request следует указать действующий дескриптор запроса, полученный ранее из DatabasePrepare. Если же передать дескриптор запроса, который был перед этим удален с помощью DatabaseFinalize (см. ниже), это приведёт к ошибке.
Функция возвращает признак успеха (true) или ошибки (false).
Общий принцип работы с повторяющимися запросами показан в следующем псевдо-коде. Часть из примененных функций — DatabaseBind, DatabaseRead — описана в следующих разделах и будет "упакована" в классы ORM.
struct Data // пример структуры
|
После того как необходимость в подготовленном запросе отпала, следует освободить занимаемые им ресурсы компьютера с помощью DatabaseFinalize.
void DatabaseFinalize(int request)
Функция удаляет запрос с указанным дескриптором, созданный в DatabasePrepare.
В случае передачи некорректного дескриптора функция выставит в _LastError ошибку ERR_DATABASE_INVALID_HANDLE.
При закрытии базы с помощью DatabaseClose все дескрипторы запросов, созданные для неё, автоматически удаляются и становятся недействительными.
Дополним наш ORM-слой (DBSQLite.mqh) новым классом DBQuery для работы с подготовленными запросами. Пока в нем будет лишь функционал инициализации и деинициализации, присущий концепции RAII, но скоро мы его расширим.
class DBQuery
|
В классе DBSQLite инициируем подготовку запроса в методе prepare за счет создания экземпляра DBQuery. Все объекты запросов будем сохранять во внутреннем массиве queries в виде автоуказателей, что позволяет вызывающему коду не следить за их явным удалением.
class DBSQLite
|