Почему при записи строкового UUID во внешний источник данных MySQL в 1С возникает ошибка Truncated incorrect INTEGER value?

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

При интеграции 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. Ошибка вызвана сочетанием двух ключевых факторов:

  1. Строгий режим SQL в MySQL (версии 5.7 и выше): Начиная с версии MySQL 5.7, по умолчанию активирован режим STRICT_TRANS_TABLES. В предыдущих версиях (например, MySQL 5.6) неявное приведение некорректной строки к целому числу вызывало лишь предупреждение (warning) с подстановкой нулевого значения, поэтому запись проходила. В версии 5.7 и новее такое неявное преобразование приводит к критической ошибке 1292.
  2. Особенности объектных таблиц во внешних источниках 1С: Если таблица внешнего источника данных настроена в 1С как объектная (имеет ровно один первичный ключ), платформа при создании нового элемента через объектную модель ожидает определенного поведения от драйвера. Если ключевое поле в метаданных помечено как автоинкрементное или имеет признак Только чтение, 1С не передает готовый строковый ключ в запрос INSERT, а пытается получить сгенерированный базой числовой идентификатор. В результате формируется некорректное сопоставление типов.

Способ 1. Корректировка метаданных ключевого поля в конфигураторе 1С

Разберем по шагам, как правильно настроить таблицу внешнего источника данных в дереве метаданных конфигуратора 1С:

  1. Откроем ветку Внешние источники данных, перейдем в нужную таблицу и найдем поле первичного ключа.
  2. Убедимся, что для поля назначен строковый тип с достаточной длиной (строка фиксированной или переменной длины не менее 36 символов).
  3. Снимем флаг Только чтение у ключевого поля. Если этот флаг установлен, платформа считает, что генерация значения выполняется на стороне СУБД, и не включает поле в блок вставки.
  4. Проверим свойство Автоинкрементное — для строкового UUID оно должно быть обязательно отключено.

Способ 2. Явное заполнение первичного ключа в коде 1С

Посмотрим на пример правильной инициализации и записи нового объекта внешнего источника данных. Чтобы платформа не пыталась запросить числовой идентификатор из базы, необходимо явно передать строковый ключ перед фиксацией данных.

Для генерации уникального идентификатора и преобразования его в строку воспользуемся стандартными средствами платформы:


УникальныйИдентификатор1С = Новый УникальныйИдентификатор;
СтрокаИдентификатора = НРег(Строка(УникальныйИдентификатор1С));

НовыйОбъект = ВнешниеИсточникиДанных.ВнешняяБазаMySQL.Таблицы.МояТаблица.СоздатьЭлемент();
НовыйОбъект.Идентификатор = СтрокаИдентификатора;
НовыйОбъект.Наименование = "Тестовая запись";

// Явная фиксация ссылки нового объекта для объектной модели
НовыйОбъект.УстановитьСсылкуНового(
    ВнешниеИсточникиДанных.ВнешняяБазаMySQL.Таблицы.МояТаблица.ПолучитьСсылку(
        Новый Структура("Идентификатор", СтрокаИдентификатора)
    )
);

Попытка
    НовыйОбъект.Записать();
    Сообщить("Запись успешно добавлена!");
Исключение
    Сообщить("Ошибка при записи: " + ОписаниеОшибки());
КонецПопытки;

Способ 3. Выбор правильного формата хранения UUID в MySQL

Выясним, какие форматы хранения UUID поддерживаются в MySQL и как они согласуются с 1С:

  1. Текстовый формат VARCHAR(36) или CHAR(36): Самый простой вариант для прямой интеграции через внешние источники 1С. Данные передаются напрямую в виде строки вида 435a5350-bbc1-11e6-8269-00ff75dfd0db без дополнительных преобразований.
  2. Бинарный формат BINARY(16): Более компактный способ хранения в MySQL, уменьшающий размер индексов. В этом случае из UUID удаляются дефисы, а строка переводится в бинарный вид функцией UNHEX():
    
    -- Пример преобразования в бинарный вид на стороне MySQL:
    UNHEX(REPLACE('435a5350-bbc1-11e6-8269-00ff75dfd0db', '-', ''))
    
    -- Обратное чтение в строковый вид:
    HEX(ПолеBinary16)
    

    При использовании бинарного формата BINARY(16) штатный механизм объектных таблиц 1С не сможет напрямую сопоставить его со строкой, поэтому рекомендуется использовать текстовый формат CHAR(36) либо переходить на прямое выполнение запросов.

Альтернативные варианты интеграции

Если специфика внешнего источника данных не позволяет использовать стандартную объектную запись 1С, рассмотрим альтернативные пути решения:

  1. Прямое выполнение запросов через COM-объект ADODB.Connection: Позволяет отправлять явные параметризованные SQL-запросы в обход ограничений механизма внешних источников 1С.
  2. Использование целочисленного суррогатного ключа в MySQL: Сделайте первичным ключом поле id INT AUTO_INCREMENT (или BIGINT), а строковый UUID храните в отдельном индексированном поле с ограничением UNIQUE. В этом случае объектная модель внешних источников данных 1С будет работать со стандартным числовым автоинкрементом без сбоев.
← На главную