Как записать новую строку из таблицы 1С в базу данных MS SQL Server через ADO

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия
← На главную

Часто в практике программиста 1С возникает задача интеграции со сторонними базами данных. Разберем ситуацию, когда мы успешно подключились к базе данных MS SQL Server через COMОбъект("ADODB.Connection"), считали данные в таблицу значений на форме и теперь нам нужно добавить новые строки из этой таблицы обратно в базу MS SQL. Посмотрим по шагам, как правильно и безопасно реализовать эту процедуру.

Основы выполнения команды INSERT из 1С

Для добавления новой записи в таблицу SQL используется стандартный SQL-запрос INSERT INTO. Чтобы выполнить его из 1С через ADO, необходимо присвоить текст этого запроса свойству объекта команды и вызвать метод выполнения. Проанализируем простейший пример такого запроса:


ТекстЗапроса = "INSERT INTO BROK1.dbo.MN ([MN_DOC_NUMBER], [MN_PRODUCT], [MN_QUANTITY]) VALUES ('2', 'Продукция 1', '3')";
Команда.CommandText = ТекстЗапроса;     
Команда.Execute();

Обратите внимание, что создавать объект ADODB.RecordSet для выполнения запросов на изменение данных (INSERT, UPDATE) не требуется. Достаточно просто выполнить Команда.Execute().

Добавление данных в цикле и проверка уникальности

Если мы работаем с таблицей значений на форме и хотим записать несколько строк, нам нужно обойти коллекцию в цикле и собрать строку для вставки динамически. Однако важно учитывать, что строка может уже существовать в базе. Рассмотрим, как с помощью конструкции IF NOT EXISTS выполнить вставку только уникальных записей:


Для Каждого Стр Из Таблица Цикл
    ТекстТекущейИнструкции = "
    |IF NOT EXISTS (SELECT *
    |               FROM BROK1.dbo.MN 
    |               WHERE MN_DOC_NUMBER = '" + Стр.MN_DOC_NUMBER + "' 
    |                 AND MN_PRODUCT = '" + Стр.P_NAME + "'
    |                 AND MN_QUANTITY = '" + Стр.MN_QUANTITY + "')
    |INSERT INTO BROK1.dbo.MN ([MN_DOC_NUMBER], [MN_PRODUCT], [MN_QUANTITY])
    |VALUES ('" + Стр.MN_DOC_NUMBER + "', '" + Стр.P_NAME + "', '" + Стр.MN_QUANTITY + "')";
    
    Команда.CommandText = ТекстТекущейИнструкции;
    Команда.Execute();    
КонецЦикла;

Как легко определять только «новые» строки в 1С

Вместо того чтобы при каждой записи проверять каждую строку через сложные SQL-запросы, можно оптимизировать процесс. Выясним способ, как отслеживать состояние строк прямо в таблице значений на форме 1С:

  1. Добавьте в таблицу на форме новую колонку с типом Булево. Назовите ее ЭтоНоваяЗапись и сделайте невидимой для пользователя.
  2. Когда вы программно заполняете таблицу из SQL-базы, устанавливайте для этой колонки значение Ложь.
  3. В обработчике события ПриДобавлении (или ПередНачаломДобавления) для таблицы на форме устанавливайте новой строке значение ЭтоНоваяЗапись = Истина.

При нажатии на кнопку записи вам останется только обойти таблицу и выбрать нужные строки:


Для Каждого Стр Из Таблица Цикл
    Если Стр.ЭтоНоваяЗапись Тогда
        // Формируем текст запроса INSERT и выполняем его
    КонецЕсли;
КонецЦикла;

Безопасность и форматирование данных: избегаем ошибок SQL

При конкатенации строк (сборке запроса через "плюсы") есть большая опасность столкнуться с ошибкой синтаксиса или SQL-инъекцией. Проанализируем важные нюансы:

Экранирование кавычек. Если пользователь введет в название продукта одинарную кавычку, структура SQL-запроса сломается. Обязательно экранируйте такие символы перед вставкой в текст запроса: СтрЗаменить(Стр.P_NAME, "'", "''"). Еще лучше — использовать параметризованные запросы объекта ADODB.Command.Parameters, где в текст передается знак вопроса ?, а значение добавляется отдельным свойством.

Форматирование чисел и дат. Платформа 1С по умолчанию форматирует числа с неразрывными пробелами (например, 1 000,50). SQL-сервер не поймет такой формат и выдаст ошибку, так как ожидает числа без пробелов и с точкой. Всегда форматируйте числовые значения перед отправкой в запрос: Формат(Стр.MN_QUANTITY, "ЧРД=.; ЧГ=0").

Транзакции и правильная очистка ресурсов

Если мы добавляем несколько строк в цикле, может случиться сбой (например, нарушена уникальность или пропала связь). Чтобы база данных не осталась в наполовину заполненном состоянии, применим механизм транзакций для COM-соединения. Также рассмотрим, как избежать зависших сеансов в MS SQL Server.


Попытка
    // Начинаем транзакцию перед циклом
    Соединение.BeginTrans();
    
    Для Каждого Стр Из Таблица Цикл
        Если Стр.ЭтоНоваяЗапись Тогда
            // ... Подготовка и выполнение Command.Execute() ...
        КонецЕсли;
    КонецЦикла;
    
    // Если все прошло успешно, фиксируем изменения
    Соединение.CommitTrans();
    Сообщить("Новые записи успешно добавлены!");

Исключение
    // В случае ошибки отменяем все изменения
    Соединение.RollbackTrans();
    Сообщить("Ошибка записи данных: " + ОписаниеОшибки());
КонецПопытки;

// Обязательно закрываем соединение после выполнения всех операций!
Если Соединение <> Неопределено Тогда
    Соединение.Close();
    Соединение = Неопределено;
КонецЕсли;

Применяя эти методы, вы обеспечите безопасную, стабильную и предсказуемую работу 1С со сторонними таблицами в MS SQL Server.

← На главную