При работе с внешними источниками данных, особенно при использовании облачных решений вроде Azure SQL, разработчики часто сталкиваются с ошибкой Invalid object name '#tt1' (код ошибки SQL 208). Эта ситуация возникает в момент выполнения метода Записать() для набора записей, когда платформа 1С пытается использовать временные таблицы для оптимизации процесса записи. Разберем подробно, почему это происходит и в каких версиях платформы искать спасение.
Для начала проанализируем ситуацию: что такое #tt1? Это временная таблица, создаваемая в базе данных tempdb SQL-сервера. Префикс # означает, что таблица является локальной и привязана к конкретной сессии (SPID) или соединению. Ошибка «Invalid object name» сигнализирует о том, что платформа 1С пытается обратиться к таблице, которой в текущей сессии уже не существует.
Выясним причину исчезновения таблицы. В случае с Azure SQL это чаще всего связано с разрывом физического соединения. Облачные СУБД могут кратковременно прерывать «неактивные» (с их точки зрения) сессии для обслуживания или ребалансировки нагрузки. Если в процессе подготовки данных между созданием временной таблицы и командой MERGE (или INSERT) возникла пауза, Azure может сбросить соединение. Платформа 1С прозрачно для пользователя восстанавливает логическую сессию, но физическое соединение на стороне SQL становится новым, и старые временные таблицы в нем уже не видны.
Рассмотрим историю исправлений этой ошибки. В официальном трекере багов фирмы «1С» зафиксирована ошибка с кодом 50010160. В описании указано, что проблема с именованием временных таблиц исправлена в версии 8.3.9.2033. Однако практика показывает, что даже на более высоких версиях (например, 8.3.9.2170) ошибка продолжает возникать при работе с внешними СУБД через ODBC.
Проанализируем почему так происходит. Первоначальное исправление касалось самого механизма формирования имен, но не учитывало специфику «устойчивости соединений» (Connection Resiliency) в облаках. Полноценная стабилизация работы с внешними источниками данных была достигнута значительно позже. Рассмотрим рекомендации по версиям:
Посмотрим на программную среду. Использование старых драйверов (например, SQL Server Native Client 11.0) — прямой путь к получению ошибки 208 в Azure. Разберем, что нужно сделать:
Необходимо установить и использовать Microsoft ODBC Driver 17 for SQL Server (рекомендуемая версия — 17.2 и выше). В этой версии драйвера реализована технология Idle Connection Resiliency. Она позволяет драйверу автоматически восстанавливать сессию таким образом, чтобы временные объекты сохраняли свою валидность в определенных сценариях, или корректно сообщать платформе о необходимости пересоздания контекста.
Если обновление платформы невозможно, или ошибка сохраняется на больших объемах данных, проанализируем наш код. Ошибка часто возникает при записи огромных наборов данных, например, 100 000+ записей за один раз. В этот момент транзакция становится «длинной», и риск таймаута в Azure возрастает.
Разберем решение через разбиение записи на порции. Вместо того чтобы вызывать Набор.Записать(Замещать) для всего массива данных, воспользуемся пакетной обработкой. Посмотрим на пример кода:
// Пример записи данных порциями для внешнего источника
РазмерПорции = 1000;
ВсегоЗаписей = ТаблицаДанных.Количество();
ТекущийИндекс = 0;
Пока ТекущийИндекс < ВсегоЗаписей Цикл
Набор = ВнешниеИсточникиДанных.ИмяИсточника.Таблицы.ИмяТаблицы.СоздатьНаборЗаписей();
// Отбираем порцию данных
Для Сч = 1 По РазмерПорции Цикл
Если ТекущийИндекс >= ВсегоЗаписей Тогда
Прервать;
КонецЕсли;
НоваяЗапись = Набор.Добавить();
ЗаполнитьЗначенияСвойств(НоваяЗапись, ТаблицаДанных[ТекущийИндекс]);
ТекущийИндекс = ТекущийИндекс + 1;
КонецЦикла;
// Записываем порцию без замещения всего набора, если логика позволяет
// Или используем фильтры для частичного замещения
Набор.Записать();
КонецЦикла;
Такой подход гарантирует, что временная таблица #tt1 будет существовать в рамках короткой транзакции, что значительно снижает вероятность ее потери.
Выясним еще один важный нюанс. При работе через ODBC крайне рекомендуется включать параметр MARS (Multiple Active Result Sets). Это позволяет выполнять несколько запросов в рамках одного соединения без ожидания завершения предыдущих, что повышает стабильность сессии 1С.
В строке соединения внешнего источника данных добавьте параметр: MultipleActiveResultSets=True;. Это помогает платформе удерживать фокус на временных таблицах даже при выполнении промежуточных системных запросов к метаданным внешнего источника.
Подведем итог нашему исследованию. Ошибка Invalid object name '#tt1' — это следствие несоответствия жизненного цикла временной таблицы и жизненного цикла физического соединения в облачной среде. Для решения проблемы выполним следующие шаги:
Max DOP. Если он установлен в значение более 1, это может провоцировать блокировки в tempdb при создании временных таблиц платформой.Применяя эти методы в комплексе, мы обеспечим стабильную работу системы и избавимся от досадных прерываний при обмене данными с облачными базами данных.