При интеграции 1С с внешними базами данных, такими как PostgreSQL, разработчики часто используют технологию ADO (ActiveX Data Objects). Распространенной проблемой является ситуация, когда простые запросы на чтение данных SELECT выполняются успешно, а попытки изменить данные через UPDATE или INSERT вызывают ошибки или не приносят результата. Рассмотрим подробно, как правильно настроить подключение и выполнить команду обновления записи.
Типичная ошибка, с которой сталкиваются программисты при использовании объекта ADODB.Command, звучит так: «Не был задан текст команды для объекта команды». Происходит это из-за смешивания способов вызова методов. Разберем ситуацию на примере кода, где текст запроса передается непосредственно в метод Execute, но объект Команда при этом не инициализирован должным образом.
Для того чтобы понять, что именно идет не так, в блоке Исключение всегда рекомендуется использовать функцию ОписаниеОшибки(). Это позволит увидеть детальное сообщение от драйвера ODBC или провайдера OLE DB.
Чтобы успешно выполнить UPDATE, необходимо строго соблюдать последовательность инициализации свойств объекта ADODB.Command. Мы должны явно указать активное соединение, текст команды и тип команды. Проанализируем правильный алгоритм:
// Создаем соединение
Connection = Новый COMОбъект("ADODB.Connection");
Connection.ConnectionString = "Driver={PostgreSQL ODBC Driver(Unicode)}; Server=172.21.3.251; Port=5432; Database=set; Uid=postgres; Pwd=password;";
Connection.Open();
// Создаем объект команды
Команда = Новый COMОбъект("ADODB.Command");
Команда.ActiveConnection = Connection;
Команда.CommandType = 1; // adCmdText
// Формируем текст запроса
ТекстЗапроса = "UPDATE cards_bonusaccounts_balance
|SET ammount = 0
|WHERE bonusaccounts_id = '" + Формат(ИдБаланса, "ЧГ=0") + "'";
// Явно назначаем текст команды свойству CommandText
Команда.CommandText = ТекстЗапроса;
// Выполняем команду
Попытка
Команда.Execute();
Сообщить("Данные успешно обновлены");
Исключение
Сообщить("Ошибка при обновлении: " + ОписаниеОшибки());
КонецПопытки;
Важный нюанс: В отличие от метода Execute объекта Connection, метод Execute объекта Command ожидает, что основной текст запроса уже находится в свойстве CommandText. Если вы пытаетесь передать строку запроса параметром в Команда.Execute(ТекстЗапроса), это может привести к исключительной ситуации в некоторых версиях драйвера.
PostgreSQL очень чувствителен к типам данных и регистру имен полей. При формировании строки UPDATE из 1С обратите внимание на следующие моменты:
Формат(Значение, "ЧГ=0"). Это исключит появление неразрывных пробелов (разделителей групп разрядов), которые превратят число 1 500 в строку "1 500", вызывая ошибку синтаксиса в SQL.Ammount), их необходимо заключать в двойные кавычки: SET "Ammount" = 0. По умолчанию PostgreSQL ищет имена в нижнем регистре.Иногда запрос выполняется без ошибок, но данные в базе не меняются. Это может быть связано с тем, что драйвер ожидает явного завершения транзакции. Для гарантии записи данных рассмотрим применение методов управления транзакциями:
Попытка
Connection.BeginTrans(); // Начало транзакции
Команда.Execute();
Connection.CommitTrans(); // Фиксация изменений
Сообщить("Транзакция завершена успешно");
Исключение
Connection.RollbackTrans(); // Откат изменений при ошибке
Сообщить("Ошибка: " + ОписаниеОшибки());
КонецПопытки;
Выясним причины, по которым код может работать в pgAdmin, но не работать из 1С:
COMОбъект.Uid=postgres), должен иметь права UPDATE на конкретную таблицу. В pgAdmin вы можете работать под суперпользователем, а в строке подключения 1С использовать ограниченную учетную запись.ReadOnly=1, любые изменяющие запросы будут блокироваться.Если вы используете современную платформу 1С:Предприятие 8.3, проанализируем возможность отказа от ADODB в пользу механизма «Внешние источники данных». Это позволяет добавить таблицы PostgreSQL непосредственно в конфигурацию 1С. В этом случае работа с данными (включая UPDATE) будет происходить через привычные объектные методы 1С, а платформа сама позаботится о типизации и безопасности запросов, исключая ошибки работы с COM-объектами.