Как передать файл в поле BLOB базы данных SQLite из 1С при помощи ADO

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

Работа с внешними базами данных часто становится необходимостью, когда нужно интегрировать 1С с мобильными приложениями, веб-сервисами или локальными кэшами. SQLite является одной из самых популярных встраиваемых СУБД, однако при попытке записать в неё двоичные данные (например, изображения формата JPG или PNG) напрямую через SQL-запрос типа INSERT, разработчики сталкиваются с трудностями. В этой статье мы подробно разберем, как правильно передать файл в поле типа BLOB, используя механизмы ADO, и как избежать проблем с кодировкой кириллических символов.

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

Рассмотрим стандартную ситуацию: у нас есть путь к файлу картинки, и мы хотим добавить её в таблицу. На первый взгляд кажется, что достаточно сформировать строку запроса. Однако двоичные данные содержат спецсимволы, которые нарушат структуру SQL-команды. Кроме того, 1С не может просто «склеить» объект ДвоичныеДанные со строкой запроса. Для решения этой задачи мы будем использовать параметризацию запросов через объект ADODB.Command и вспомогательный объект ADODB.Stream для чтения файла.

Шаг 1: Подготовка соединения с SQLite

Для начала проанализируем процесс подключения. Нам потребуется установленный в системе SQLite ODBC Driver. Мы создаем объект соединения и открываем его, указывая путь к файлу базы данных. Рекомендуется использовать параметры, оптимизирующие скорость записи, так как SQLite блокирует базу при выполнении транзакций.


// Установим соединение
ФайлБД = "C:\Data\my_database.db";
SQLiteObject = Новый COMОбъект("ADODB.Connection");
// В строке подключения можно добавить SyncPragma=NORMAL для ускорения
SQLiteConnectionString = "DRIVER=SQLite3 ODBC Driver;Database=" + ФайлБД + ";";
SQLiteObject.Open(SQLiteConnectionString);

Шаг 2: Использование ADODB.Command для параметризации

Чтобы передать бинарный файл, нам нужно отказаться от прямой сборки строки запроса и перейти к использованию параметров (символы ? в тексте запроса). Это не только позволяет передавать BLOB, но и защищает от SQL-инъекций. Разберем создание команды:


cmd = Новый COMОбъект("ADODB.Command");
cmd.ActiveConnection = SQLiteObject;
// Используем знаки вопроса как заполнители для параметров
cmd.CommandText = "INSERT INTO Goods (_id, _name, _text, _jpg) VALUES (?, ?, ?, ?)";
cmd.CommandType = 1; // adCmdText

Шаг 3: Чтение файла через ADODB.Stream

Поскольку 1С передает данные в COM-объекты в своем специфическом формате, напрямую передать объект ДвоичныеДанные в параметр ADO не получится — это вызовет ошибку несоответствия типов. Нам поможет ADODB.Stream, который прочитает файл в массив байтов, понятный драйверу ODBC.

Проанализируем процедуру подготовки бинарных данных:


ПутьКФайлу = "C:\Images\item_001.jpg";
ФайлКартинки = Новый Файл(ПутьКФайлу);

Если ФайлКартинки.Существует() Тогда
    StreamIn = Новый COMОбъект("ADODB.Stream");
    StreamIn.Type = 1; // adTypeBinary (двоичные данные)
    StreamIn.Open();
    StreamIn.LoadFromFile(ПутьКФайлу);
    
    // Читаем всё содержимое в переменную
    БинарныеДанные = StreamIn.Read(); 
    РазмерФайла = StreamIn.Size;
    StreamIn.Close();
Иначе
    БинарныеДанные = Неопределено;
    РазмерФайла = 0;
КонецЕсли;

Шаг 4: Привязка параметров и выполнение запроса

Теперь самое важное — правильно типизировать параметры. Выясним причину частой ошибки «Аргументы имеют неверный тип». Она возникает, если константы типов ADO указаны неверно. Рассмотрим основные типы:

  1. 202 (adVarWChar) — для строк Unicode (кириллица).
  2. 205 (adLongVarBinary) — для больших двоичных данных (BLOB).

Приступим к сборке и выполнению:


// Очистим параметры, если команда используется в цикле
cmd.Parameters.Refresh(); 

// Добавляем строковые параметры (ID и Наименование)
// Используем 202 тип (adVarWChar) для корректной передачи кириллицы
cmd.Parameters.Append(cmd.CreateParameter("@Id", 202, 1, 100, СокрЛП(Выборка.ID)));
cmd.Parameters.Append(cmd.CreateParameter("@Name", 202, 1, 255, СокрЛП(Выборка.Наименование)));
cmd.Parameters.Append(cmd.CreateParameter("@Text", 202, 1, 1000, СокрЛП(Выборка.Описание)));

// Добавляем параметр BLOB
Если БинарныеДанные <> Неопределено Тогда
    // Тип 205 - adLongVarBinary, 1 - adParamInput
    cmd.Parameters.Append(cmd.CreateParameter("@Jpg", 205, 1, РазмерФайла, БинарныеДанные));
Иначе
    // Если картинки нет, передаем NULL (тип 205 с размером 0 или специальный Null)
    cmd.Parameters.Append(cmd.CreateParameter("@Jpg", 205, 1, 1, Неопределено));
КонецЕсли;

cmd.Execute();

Важный момент: если объем файла очень большой, вместо прямой передачи Value можно использовать метод AppendChunk. Это позволит передавать данные порциями, минимизируя нагрузку на память.

Решение проблемы с кириллицей и типом BLOB

Многие разработчики замечают, что при записи кириллических строк в SQLite через ADO, данные в базе отображаются как BLOB или некорректные символы. Выясним причину: SQLite по умолчанию ожидает UTF-8. Если в методе CreateParameter вы используете тип 200 (adVarChar), драйвер пытается передать строку в ANSI-кодировке. Если она не соответствует системной локали или содержит специфические символы, SQLite может интерпретировать входящий поток байтов как бинарный.

Решение: Всегда используйте тип 202 (adVarWChar). Это заставляет ADO передавать данные в формате WideChar (Unicode), который корректно обрабатывается современными ODBC-драйверами SQLite и правильно преобразуется в UTF-8 внутри базы.

Альтернативный подход: Внешние источники данных

Если ваша конфигурация работает на платформе 8.3.x, стоит рассмотреть использование механизма «Внешние источники данных». Это значительно упрощает работу:

  1. Вы подключаете SQLite базу в дереве конфигурации.
  2. Поля BLOB автоматически отображаются как тип ХранилищеЗначения.
  3. Вам не нужно заботиться о COM-объектах ADODB.Stream или Command.
  4. Запись файла сводится к обычному присвоению: НоваяСтрока.ПолеКартинки = Новый ХранилищеЗначения(ДвоичныеДанные);.

Этот способ является более «нативным» для 1С и рекомендуется для новых разработок, так как он платформенно независим и работает в том числе на Linux-серверах (при наличии соответствующего драйвера).

Заключение

Мы рассмотрели детальный алгоритм записи изображений в SQLite. Подытожим основные правила: используйте ADODB.Command для безопасности и работы с параметрами, применяйте ADODB.Stream для корректного чтения бинарных файлов и не забывайте про Unicode-типы параметров (202) для текстовых полей, чтобы избежать проблем с кириллицей. Такой подход обеспечит стабильную работу интеграции и целостность ваших данных.

← На главную