При интеграции 1С со сторонними реляционными базами данных через механизм Внешние источники данных разработчики нередко сталкиваются со специфическими ошибками драйвера ODBC. Одной из типичных проблем является сбой при попытке создать новую запись в таблице MySQL, где первичным ключом выступает строковый уникальный идентификатор (UUID) длиной 36 символов (например, e6e12e11-022a-11e6-85df-00e018f3c64a).
В процессе выполнения операции платформа 1С возвращает исключение следующего вида:
Ошибка внешней базы данных: ошибка при выполнении запроса по причине: Ошибка ODBC. SQLSTATE: HY000. Номер ошибки: 1292. Описание: [MySQL][ODBC 5.3(w) Driver][mysqld-5.7.16-log]Truncated incorrect INTEGER value: '435a5350-bbc1-11e6-8269-00ff75dfd0db'
Разберем подробнее, почему СУБД воспринимает строковый идентификатор как целочисленное значение (INTEGER), и рассмотрим по шагам, как исправить данную ошибку.
Проанализируем ситуацию на стыке платформы 1С и СУБД MySQL. Ошибка вызвана сочетанием двух ключевых факторов:
STRICT_TRANS_TABLES. В предыдущих версиях (например, MySQL 5.6) неявное приведение некорректной строки к целому числу вызывало лишь предупреждение (warning) с подстановкой нулевого значения, поэтому запись проходила. В версии 5.7 и новее такое неявное преобразование приводит к критической ошибке 1292.INSERT, а пытается получить сгенерированный базой числовой идентификатор. В результате формируется некорректное сопоставление типов.Разберем по шагам, как правильно настроить таблицу внешнего источника данных в дереве метаданных конфигуратора 1С:
Посмотрим на пример правильной инициализации и записи нового объекта внешнего источника данных. Чтобы платформа не пыталась запросить числовой идентификатор из базы, необходимо явно передать строковый ключ перед фиксацией данных.
Для генерации уникального идентификатора и преобразования его в строку воспользуемся стандартными средствами платформы:
УникальныйИдентификатор1С = Новый УникальныйИдентификатор;
СтрокаИдентификатора = НРег(Строка(УникальныйИдентификатор1С));
НовыйОбъект = ВнешниеИсточникиДанных.ВнешняяБазаMySQL.Таблицы.МояТаблица.СоздатьЭлемент();
НовыйОбъект.Идентификатор = СтрокаИдентификатора;
НовыйОбъект.Наименование = "Тестовая запись";
// Явная фиксация ссылки нового объекта для объектной модели
НовыйОбъект.УстановитьСсылкуНового(
ВнешниеИсточникиДанных.ВнешняяБазаMySQL.Таблицы.МояТаблица.ПолучитьСсылку(
Новый Структура("Идентификатор", СтрокаИдентификатора)
)
);
Попытка
НовыйОбъект.Записать();
Сообщить("Запись успешно добавлена!");
Исключение
Сообщить("Ошибка при записи: " + ОписаниеОшибки());
КонецПопытки;
Выясним, какие форматы хранения UUID поддерживаются в MySQL и как они согласуются с 1С:
VARCHAR(36) или CHAR(36): Самый простой вариант для прямой интеграции через внешние источники 1С. Данные передаются напрямую в виде строки вида 435a5350-bbc1-11e6-8269-00ff75dfd0db без дополнительных преобразований.BINARY(16): Более компактный способ хранения в MySQL, уменьшающий размер индексов. В этом случае из UUID удаляются дефисы, а строка переводится в бинарный вид функцией UNHEX():
-- Пример преобразования в бинарный вид на стороне MySQL:
UNHEX(REPLACE('435a5350-bbc1-11e6-8269-00ff75dfd0db', '-', ''))
-- Обратное чтение в строковый вид:
HEX(ПолеBinary16)
При использовании бинарного формата BINARY(16) штатный механизм объектных таблиц 1С не сможет напрямую сопоставить его со строкой, поэтому рекомендуется использовать текстовый формат CHAR(36) либо переходить на прямое выполнение запросов.
Если специфика внешнего источника данных не позволяет использовать стандартную объектную запись 1С, рассмотрим альтернативные пути решения:
ADODB.Connection: Позволяет отправлять явные параметризованные SQL-запросы в обход ограничений механизма внешних источников 1С.id INT AUTO_INCREMENT (или BIGINT), а строковый UUID храните в отдельном индексированном поле с ограничением UNIQUE. В этом случае объектная модель внешних источников данных 1С будет работать со стандартным числовым автоинкрементом без сбоев.