Интеграция сторонних баз данных с платформой «1С:Предприятие» через механизм Внешних источников данных — это мощный инструмент, упрощающий обмен информацией и построение сквозных бизнес-процессов. Однако при попытке не просто прочитать, но и записать данные обратно в стороннюю СУБД, разработчики часто сталкиваются со специфическими ошибками совместимости типов данных. Одной из самых распространенных является ошибка конвертации даты при работе с СУБД Firebird через ODBC-драйвер.
В этой статье мы подробно проанализируем, почему возникает ошибка conversion error from string при попытке обновить запись в таблице Firebird, разберем причины конфликта типов данных и рассмотрим три эффективных способа решения этой проблемы в зависимости от ваших задач и уровня доступа к сторонней базе данных.
Давайте рассмотрим типичную ситуацию. В 1С настроено подключение к внешнему источнику. Мы находим нужную строку таблицы и пытаемся изменить лишь одно числовое поле DELTA, не трогая поля с датами:
СтрокаВИ = ВнешниеИсточникиДанных.ВИ.Таблицы.COUNTERD.НайтиПоПолю("ID", 2);
ОбТекстрока = СтрокаВИ.ПолучитьОбъект();
ОбТекстрока.DELTA = 36;
ОбТекстрока.Записать();
При выполнении метода Записать() платформа генерирует и отправляет через ODBC-драйвер SQL-запрос обновления (UPDATE). В результате мы получаем ошибку следующего вида:
Ошибка ODBC. SQLSTATE: HY000. Номер ошибки: -413. Описание: [ODBC Firebird Driver][Firebird]conversion error from string "2019-11-29 00:00:00"
Выясним причину такого поведения. Дело в принципиальном различии хранения типов даты и времени в 1С и Firebird:
Дата всегда является составным — он содержит и календарную дату, и время (даже если время не указано в явном виде, оно по умолчанию равно 00:00:00).DATE хранит исключительно дату (без времени), поле TIME — только время, а поле TIMESTAMP — дату и время одновременно.DELTADATE, имеющее в Firebird тип DATE, получает от 1С строковое представление даты и времени в формате "YYYY-MM-DD HH:MM:SS". Драйвер ODBC пытается напрямую записать эту строку в поле DATE. Поскольку в Firebird Dialect 3 неявное приведение строки формата Timestamp к чистому типу DATE запрещено, СУБД возвращает ошибку -413."0001-01-01 00:00:00", что гарантированно вызывает сбой при парсинге ODBC-драйвером.Если для бизнес-логики вашей задачи поля с датой (например, DELTADATE и DELTATIME) обновлять не требуется, а нужно лишь изменить числовой показатель DELTA, самым простым и безопасным решением будет редактирование состава внешнего источника данных в конфигураторе 1С.
Разберем этот процесс по шагам:
COUNTERD) и перейдите на вкладку Поля.Дата и вызывают ошибку конвертации.После этого платформа 1С при вызове метода Записать() больше не будет пытаться передавать значения этих полей в SQL-запросе UPDATE. Это мгновенно решит проблему со строковой ошибкой приведения типов.
Иногда после исключения проблемных полей из метаданных 1С мы можем натолкнуться на другую ошибку СУБД:
Ошибка ODBC. SQLSTATE: HY000. Номер ошибки: -836. Описание: [ODBC Firebird Driver][Firebird]exception 9. E_EDIT_FORBIDDEN. Редактирование запрещено. At trigger 'UPD_BEF_COUNTERD0'
Проанализируем ситуацию. Данная ошибка означает, что на стороне Firebird сработал внутренний триггер (в данном случае UPD_BEF_COUNTERD0, выполняющийся перед обновлением записи), который заблокировал транзакцию. Это происходит по следующим причинам:
Чтобы решить эту проблему, необходимо проанализировать триггер внутри СУБД Firebird. Сделать это из 1С напрямую невозможно. Выполните следующие действия:
isql).SYSDBA).COUNTERD и перейдите к списку её триггеров.UPD_BEF_COUNTERD0. Скорее всего, вы обнаружите условие, которое запрещает редактирование записи, если определенные поля пусты или не соответствуют заданным критериям безопасности.Если изменять структуру таблиц СУБД запрещено, а редактировать метаданные 1С нежелательно, мы можем отказаться от высокоуровневой объектной техники записи 1С (метода Записать()) и перейти к использованию прямых параметризованных SQL-запросов. Это позволит нам полностью контролировать передаваемый в СУБД синтаксис и использовать встроенные функции преобразования типов.
Рассмотрим пример реализации такого подхода с использованием явного приведения типов с помощью конструкции CAST на стороне Firebird. Для этого воспользуемся возможностями прямого выполнения запросов во внешнем источнике данных или через внешнее соединение ADODB.Connection:
// Пример записи данных через прямое выполнение SQL-запроса
ТекстЗапроса = "UPDATE COUNTERD
SET DELTA = ?,
DELTADATE = CAST(? AS DATE)
WHERE ID = ?";
// В параметр для DELTADATE передается строка из 1С в формате "YYYY-MM-DD"
// Использование CAST(? AS DATE) заставит Firebird корректно преобразовать строку
Использование конструкции CAST(? AS DATE) заставляет Firebird самостоятельно и корректно преобразовать переданную из 1С строку в соответствующий тип данных DATE на этапе компиляции SQL-запроса, полностью исключая возникновение ошибки -413.
Если вы являетесь администратором или разработчиком интегрируемой базы данных Firebird, самым надежным и архитектурно правильным решением будет изменение типа данных самой колонки. Если изменить тип поля DELTADATE с DATE на TIMESTAMP, это решит проблему совместимости раз и навсегда.
Тип TIMESTAMP в Firebird хранит и дату, и время, поэтому он без каких-либо ошибок и дополнительных преобразований принимает строковые значения формата "YYYY-MM-DD HH:MM:SS", которые 1С передает по умолчанию при записи объектов внешних источников данных.
Для изменения типа поля в Firebird выполните следующий SQL-скрипт:
ALTER TABLE COUNTERD ALTER COLUMN DELTADATE TYPE TIMESTAMP;
После этого обновите структуру внешнего источника данных в 1С. Объектная техника записи начнет работать в штатном режиме без ошибок конвертации и без необходимости переписывать код на стороне 1С.
При работе с внешними источниками данных через ODBC также крайне важно обращать внимание на технические нюансы окружения:
Dialect=3;. Использование устаревшего Dialect 1 может маскировать часть ошибок при чтении, но приводить к непредсказуемому поведению при записи дат.fbclient.dll строго той же версии и разрядности (x86 или x64), под управлением которой работает сам сервер СУБД Firebird. Различие в версиях клиента и сервера часто является скрытой причиной некорректной сериализации дат.Применяя описанные подходы, мы сможем эффективно настроить стабильный обмен данными между «1С:Предприятием» и СУБД Firebird, избегая ошибок преобразования типов и конфликтов с внутренними триггерами базы данных.