Как передать изображение из 1С в поле LONGBLOB базы данных MySQL?

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

При интеграции систем часто возникает необходимость выгрузить графические файлы (фотографии товаров, скан-копии документов, штрихкоды) из информационной базы 1С напрямую во внешнюю базу данных MySQL. В MySQL для хранения бинарных данных большого объема традиционно используется тип LONGBLOB. Однако при попытке записать файл в таблицу разработчики часто сталкиваются с ситуацией, когда запрос выполняется без явных синтаксических ошибок, но данные в поле не обновляются.

Разберем подробно, почему популярный способ с функцией LOAD_FILE() может не работать, а также рассмотрим надежные альтернативные варианты прямой передачи двоичных данных из кода 1С.

Почему не работает LOAD_FILE в MySQL: разбор причин

Один из первых способов, который пробуют разработчики — вызвать встроенную функцию MySQL:

UPDATE photo SET HIRES_RASTER = LOAD_FILE("D:\Новая папка\1.jpg") WHERE id = 514;

В результате СУБД возвращает статус Rows matched: 1 Changed: 0, а в поле записывается NULL. Проанализируем ключевые причины такого поведения:

  1. Некорректное экранирование обратных слэшей. В языке SQL обратный слэш \ является спецсимволом экранирования. Строка вида "D:\Новая папка\1.jpg" воспринимается парсером как символы \N и \1. Путь необходимо указывать либо с прямыми слэшами: "D:/Новая папка/1.jpg", либо удваивать обратные слэши: "D:\\Новая папка\\1.jpg".
  2. Местоположение файла относительно сервера. Функция LOAD_FILE() выполняется строго на стороне сервера СУБД и ищет файл в локальной файловой системе машины, где установлен MySQL. Если служба MySQL запущена на отдельном сервере или в Docker-контейнере, путь D:\Новая папка\1.jpg на клиентском компьютере или сервере 1С для нее просто не существует.
  3. Ограничение системной переменной secure_file_priv. Для безопасности в MySQL директория чтения файлов жестко ограничена. Если значение переменной равно NULL, импорт файлов через LOAD_FILE() полностью заблокирован. Если там указан путь (например, папка Uploads), файл обязан лежать именно внутри нее. Проверить настройку можно командой: SHOW VARIABLES LIKE 'secure_file_priv';.
  4. Права службы и учетной записи. Служба MySQL в операционной системе должна иметь права на чтение указанной папки и файла. Кроме того, учетная запись MySQL, под которой вы подключились, должна обладать глобальной системной привилегией FILE.
  5. Превышение размера max_allowed_packet. Если размер файла превышает лимит системного параметра max_allowed_packet, функция возвратит NULL.

Ввиду этих ограничений передача файла через LOAD_FILE() создает сильную зависимость от файловой системы сервера MySQL. Поэтому предпочтительнее передавать бинарное содержимое файла непосредственно из контекста 1С.

Способ 1. Передача двоичных данных через HEX-строку (рекомендуемый вариант)

Рассмотрим наиболее универсальный и надежный подход. Мы считываем файл на стороне 1С в объект ДвоичныеДанные, переводим его в шестнадцатеричную строку и передаем в SQL-запрос. В MySQL для восстановления исходного бинарного вида применяется встроенная функция UNHEX() или шестнадцатеричный литерал 0x.

Посмотрим на пример кода на платформе 1С:


ПутьКФайлу = "D:/Новая папка/1.jpg";
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
СтрокаHex = ПолучитьHexСтрокуИзДвоичныхДанных(ДвоичныеДанныеФайла);

ИДЗаписи = 514;
ТекстЗапроса = "UPDATE photo SET HIRES_RASTER = UNHEX('" + СтрокаHex + "') WHERE id = " + Формат(ИДЗаписи, "ЧГ=0") + ";";

// Выполняем полученный ТекстЗапроса через установленное соединение с СУБД

Обратите внимание: также допустимо передавать данные через префикс шестнадцатеричного литерала: SET HIRES_RASTER = 0x.... Однако при использовании функции UNHEX() синтаксис остается более наглядным при сборке параметризованных запросов.

Способ 2. Кодирование файла в Base64

Еще один распространенный способ — кодирование файла в строку стандарта Base64. Начиная с версии MySQL 5.6.1, в СУБД доступна встроенная функция FROM_BASE64(), преобразующая закодированный текст обратно в бинарный блоб.

Разберем по шагам реализацию этого механизма:


ПутьКФайлу = "D:/Новая папка/1.jpg";
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
СтрокаBase64 = Base64Строка(ДвоичныеДанныеФайла);

ИДЗаписи = 514;
ТекстЗапроса = "UPDATE photo SET HIRES_RASTER = FROM_BASE64('" + СтрокаBase64 + "') WHERE id = " + Формат(ИДЗаписи, "ЧГ=0") + ";";

Сравним Base64 и HEX: при кодировании в Base64 размер текста запроса возрастает примерно на 33%, тогда как HEX удваивает объем данных (каждый байт кодируется двумя символами). Однако Base64 требует более современной версии MySQL.

Способ 3. Передача через ADODB.Command и ADODB.Stream (для ОС Windows)

Если сервер 1С работает под управлением Windows и подключение к MySQL осуществляется через COM-технологию ADODB.Connection, можно передавать данные напрямую в бинарном виде через параметры команды, не перегружая строку SQL длинными строковыми литералами.

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


// Создаем поток и загружаем в него бинарный файл
Поток = Новый COMОбъект("ADODB.Stream");
Поток.Type = 1; // adTypeBinary
Поток.Open();
Поток.LoadFromFile("D:\Новая папка\1.jpg");

// Настраиваем команду ADODB
Команда = Новый COMОбъект("ADODB.Command");
Команда.ActiveConnection = СоединениеMySQL; // Открытый ADODB.Connection
Команда.CommandText = "UPDATE photo SET HIRES_RASTER = ? WHERE id = ?;";

// Создаем параметр для BLOB-поля (adLongVarBinary = 205, adParamInput = 1)
РазмерДанных = Поток.Size;
ПараметрДанные = Команда.CreateParameter("p_raster", 205, 1, РазмерДанных, Поток.Read());
Команда.Parameters.Append(ПараметрДанные);

// Создаем параметр для идентификатора (adInteger = 3, adParamInput = 1)
ПараметрИД = Команда.CreateParameter("p_id", 3, 1, , 514);
Команда.Parameters.Append(ПараметрИД);

// Выполняем команду
Команда.Execute();

Поток.Close();

Важное ограничение: данный способ задействует COM-объекты Windows. Если сервер 1С функционирует на базе Linux, COM-соединения будут недоступны. Для кроссплатформенных сред рекомендуется использовать прямую генерацию HEX/Base64 запросов, либо передавать файлы во внешний сервис через объект HTTPСоединение.

Настройка сервера MySQL при работе с большими объектами

При передаче файлов любого типа через SQL-запросы обязательно проверьте параметр max_allowed_packet в конфигурационном файле MySQL (my.ini или my.cnf). По умолчанию он может быть равен 4 или 16 мегабайтам. Если передаваемый файл (с учетом накладных расходов кодирования HEX или Base64) превысит этот лимит, СУБД сбросит сетевое соединение с ошибкой Packet too large.

Для стабильной загрузки изображений высокого разрешения рекомендуется задать значение параметра с запасом, например:

max_allowed_packet = 64M

После внесения изменений в файл конфигурации необходимо перезапустить службу MySQL.

← На главную