В современной разработке на платформе 1С часто возникает необходимость интеграции с локальными базами данных, такими как SQLite. Это может быть связано с чтением данных из стороннего ПО, мобильных приложений или логов. Рассмотрим подробно, как организовать чтение данных из SQLite, разберем типичные ошибки подключения и выясним, почему стандартные драйверы иногда «не видят» базу данных.
Предположим, у нас есть файл базы данных SQLite (например, сформированный внешней программой). Нам необходимо прочитать из него данные, используя встроенный язык 1С. Для решения этой задачи чаще всего используется технология ADO (ActiveX Data Objects), которая позволяет работать с внешними источниками данных через ODBC-драйвер.
Для работы нам потребуется установленный в системе драйвер SQLite3 ODBC Driver. Однако, как показывает практика, простой установки драйвера недостаточно — важно учитывать архитектуру приложения.
Одной из самых частых проблем при подключении к SQLite из 1С является ошибка: "Источник данных не найден и не указан драйвер, используемый по умолчанию". Рассмотрим ситуацию: вы скачали и установили драйвер x64 на 64-битную операционную систему, но 1С все равно выдает ошибку при вызове метода Open().
Выясним причину: Тонкий и Толстый клиенты 1С для Windows чаще всего являются 32-битными (x86) приложениями. 32-битное приложение 1С физически не может взаимодействовать с 64-битным драйвером ODBC. Для успешного подключения необходимо устанавливать именно 32-битную версию драйвера (обычно файл называется sqliteodbc.exe, а не sqliteodbc_w64.exe).
Проанализируем шаги для исправления этой ситуации:
C:\Windows\SysWOW64\odbcad32.exe.Разберем программный код для инициализации соединения и выполнения запроса. Мы будем использовать объект ADODB.Connection.
Создадим функцию для инициализации соединения. Обратите внимание на формирование строки подключения (Connection String). Важным параметром здесь является DRIVER=SQLite3 ODBC Driver; — это имя должно в точности совпадать с тем, как драйвер зарегистрирован в системе.
Функция SQLiteInit(ФайлБД) Экспорт
// Создаем объект соединения через COM
SQLiteObject = Новый COMОбъект("ADODB.Connection");
// Формируем строку подключения. Указываем драйвер и путь к файлу базы
SQLiteConnectionString = "DRIVER=SQLite3 ODBC Driver;Database=" + ФайлБД + ";";
Попытка
// Пытаемся открыть соединение
SQLiteObject.Open(SQLiteConnectionString);
Возврат SQLiteObject;
Исключение
Сообщить("Не удалось подключиться к SQLite: " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
КонецФункции
После того как соединение установлено, мы можем выполнять SQL-запросы. Для получения данных удобно использовать объект ADODB.Recordset. Для ознакомления с практическими примерами выполнения запросов к внешним базам подойдёт руководство по подключению и получению данных из SQL в 1С.
Рассмотрим пример функции, которая выполняет запрос SELECT и возвращает набор данных, который затем можно обработать в цикле.
Процедура ПрочитатьДанныеИзSQLite(ПутьКФайлу)
Соединение = SQLiteInit(ПутьКФайлу);
Если Соединение = Неопределено Тогда
Возврат;
КонецЕсли;
ТекстЗапроса = "SELECT * FROM units";
Попытка
// Выполняем запрос напрямую через соединение
РезультатЗапроса = Соединение.Execute(ТекстЗапроса);
// Перебираем записи, пока не достигнем конца (EOF)
Пока НЕ РезультатЗапроса.EOF Цикл
// Доступ к полям осуществляется через коллекцию Fields
Идентификатор = РезультатЗапроса.Fields("id").Value;
Наименование = РезультатЗапроса.Fields("name").Value;
Сообщить("Найдено: " + Идентификатор + " / " + Наименование);
// Обязательно переходим к следующей строке
РезультатЗапроса.MoveNext();
КонецЦикла;
// Закрываем соединение после работы
Соединение.Close();
Исключение
Сообщить("Ошибка при выполнении запроса: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Проанализируем важные нюансы, которые могут возникнуть при чтении данных. SQLite использует динамическую типизацию. Это означает, что в одной колонке могут теоретически находиться данные разных типов. При использовании ADO это иногда приводит к тому, что драйвер неправильно определяет тип колонки, ориентируясь на первые несколько строк.
Чтобы избежать ошибок приведения типов, рекомендуется использовать явное приведение в самом SQL-запросе с помощью функции CAST. Например:
SELECT CAST(id AS TEXT) as id_text, name FROM units
Также стоит помнить о кодировках. SQLite хранит данные в UTF-8, а 1С внутри себя использует UTF-16. При использовании качественного ODBC-драйвера перекодировка происходит автоматически, но если вы видите «кракозябры», проверьте настройки драйвера в системном DSN (Data Source Name).
Если ваша «программка», создающая базу, активно пишет в нее в то время, как 1С пытается прочитать данные, вы можете столкнуться с ошибкой "Database is locked". SQLite по умолчанию блокирует файл на время записи.
Чтобы этого избежать, мы можем перевести базу в режим WAL (Write-Ahead Logging). В этом режиме читатели не блокируют писателей, и наоборот. Это можно сделать, выполнив специальную команду (PRAGMA) сразу после открытия соединения:
Соединение.Execute("PRAGMA journal_mode=WAL;");
Если работа через ODBC кажется слишком громоздкой или возникают проблемы с установкой драйверов на клиентские машины, рассмотрим альтернативные варианты:
sqlite3.exe с параметрами командной строки, выгружать результат в текстовый файл и затем читать его в 1С. Это «костыльный» метод, но он работает без установки драйверов.Подведем итог: Основной залог успеха при интеграции 1С и SQLite — правильный выбор разрядности драйвера. Если ваша 1С 32-битная, ставьте драйвер x86. Используйте стандартные объекты COMОбъект("ADODB.Connection") для работы и не забывайте закрывать соединения, чтобы не оставлять файл базы данных заблокированным.