Простая работа с MySQL из 1С

«Класс» для упрощения работы с MySQL из 1С. Позволяет просто выполнять любые виды запросов и получать данные в виде таблицы значений.

Для соединения используется MySQL ODBC Connector

// Подключение к базе данных
ИмяODBC = "local_base";
ИмяБазы = "base_name";
ИмяПользователя = "base_name_user";
Пароль = "*******";

MySQL = Обработки.MySQL.Создать();
MySQL.Инициализация(ИмяODBC, ИмяБазы, ИмяПользователя, Пароль);

Если НЕ MySQL.УстановитьСоединение(Ложь) Тогда
Сообщить(MySQL.ОписаниеОшибки);
Возврат Ложь;
КонецЕсли;
// Получение таблицы значений и работа с ней
Запрос =
"SELECT order_id,
|  order_date,
|  order_summ,
|  order_customer
|FROM tamble_orders
|WHERE order_loaded=""N""";

ТаблицаЗаказов = MySQL.ПолучитьТаблицуЗначенийПоЗапросу(Запрос);

Если ТаблицаЗаказов = Неопределено Тогда
Сообщить(MySQL.ОписаниеОшибки);
Возврат Ложь;
КонецЕсли;

Если ТаблицаЗаказов.Количество() = 0 Тогда
Сообщить("На сайте нет новых заказов для загрузки.");
Иначе
Для Каждого СтрокаТЗ ИЗ ТаблицаЗаказов Цикл
НомерЗаказа = СтрокаТЗ.order_id;
Покупатель = СтрокаТЗ.order_customer;
КонецЦикла;
КонецЕсли;
// Добавление новых записей в таблицу базы MySQL
// Одиночная запись
// Соответствие со значениями полей для новой записи таблицы
Товар = Новый Соответствие();
Товар["product_id"] = "158742";
Товар["product_name"] = "1С Управление торговлей 10.3";
Товар["product_price"] = 12000;

// Построение запроса
MySQL.СоздатьЗапрос("INSERT", "table_products", Товар);
// Выполнение
Если НЕ MySQL.ВыполнитьЗапрос() Тогда
Сообщить(MySQL.ОписаниеОшибки);
Возврат Ложь;
КонецЕсли;

// Несколько записей
// Массив в который вставляются соответстия
НовыеТовары = Новый Массив();

Товар = Новый Соответствие();
Товар["product_id"] = "158742";
Товар["product_name"] = "1С Управление торговлей, редакция 10.3";
Товар["product_price"] = 12000;
НовыеТовары.Добавить(Товар);

Товар = Новый Соответствие();
Товар["product_id"] = "158743";
Товар["product_name"] = "1С Управление торговлей, редакция 11";
Товар["product_price"] = 12500;
НовыеТовары.Добавить(Товар);

MySQL.СоздатьЗапрос("INSERT", "table_products", НовыеТовары);
Если НЕ MySQL.ВыполнитьЗапрос() Тогда
Сообщить(MySQL.ОписаниеОшибки);
Возврат Ложь;
КонецЕсли;
// Обновление полей записи
// Соответствие с новыми значениями полей
Товар = Новый Соответствие();
Товар["product_price"] = 13000;
Товар["product_rest"] = 10;

// В четвертом параметре можно указать условие, по которым осуществляется поиск записей для обновления
MySQL.СоздатьЗапрос("UPDATE", "table_products", Товар, "WHERE product_id='158742'");
Если НЕ MySQL.ВыполнитьЗапрос() Тогда
Сообщить(MySQL.ОписаниеОшибки);
Возврат Ложь;
Иначе
Сообщить("Обновлено товаров: " + MySQL.КоличествоИзменныхЗаписей);
КонецЕсли;
// Выполнение произвольного запроса
Запрос = "DELETE FROM table_products WHERE product_id='158742'";

Если НЕ MySQL.ВыполнитьЗапрос(Запрос) Тогда
Сообщить(MySQL.ОписаниеОшибки);
Возврат Ложь;
КонецЕсли;

Есть возможность разбить INSERT запрос с несколькими записями на подзапросы, чтобы не вставлять за раз много значений. Например, при добавлении в таблицу более 1000 записей, можно сделать это 10-ю запросами по 100 записей в каждом. Для этого достаточно вызвать код:

MySQL.ЭлементовВЗапросе = 100;

После этого все массивные INSERTы будут делаться по 100 записей за раз.
Полный текст запроса можно получить так:

MySQL.СоздатьЗапрос("INSERT", "table_products", НовыеТовары);
Сообщить(MySQL.ТекстЗапроса());

В случае, когда прямой доступ к MySQL запрещен, можно воспользоваться ssh-туннелем.  Для этого в обработке есть настройки для запуска Putty.

MySQL.ИспользоватьPutty = Истина;
MySQL.Putty = "c:Program FilesPuTTYputty.exe"; // Путь к программе Putty (Kitty)
MySQL.User_put = "ssh_user"; // Имя пользователя для установки ssh-соединения
MySQL.Pass_put = "******"; // Пароль
MySQL.Name_put = "session_name"; // Имя сохраненной сесии Putty с настройками соединения

22 Comments

  1. MegaSwitch

    Вот тут что-то похожее, только с использованием внешней компоненты.

    Reply
  2. salexdv

    (1) MegaSwitch, спасибо за ссылку! Внешние компоненты я люблю, но тут все достаточно просто и легко реализуется на встроенном языке. Единственное «неудобство» — это то, что Putty для SSH висит отдельным процессом и никак не контролируется, хотя проблем с этим не возникало.

    Reply
  3. MegaSwitch
    Putty для SSH висит отдельным процессом и никак не контролируется

    Вот как раз во этой причине в компоненте встроен ssh-клиент и полностью контролируется из 1С.

    Так же, если присвоить СозданныйComObject = Неопределено, соединение автоматически закрывается с освобождением памяти.

    У меня была практика использования Putty с 1С, но периодически клиент зависал, и приходилось убивать его руками, т.к. он занимал порт 3306.

    К тому же, были какие-то проблемы при работе в клиент-серверном варианте, но какие — уже не помню.

    Reply
  4. salexdv

    (3) MegaSwitch, тут никаких проблем не наблюдается. Putty запустился, обмен выполнился, при закрытии соединения Putty убился и все хорошо.

    Reply
  5. vasyak319
    Товар = Новый Соответстие()

    Не откомпилируется.

    Reply
  6. salexdv

    (5) vasyak319, спасибо, поправил.

    Reply
  7. ExpertAdmin

    Не работает с УТ 11.1.10

    Reply
  8. salexdv

    (7) Что именно не работает? Какой код выполняете? Какую ошибку возвращает?

    Reply
  9. al2ko

    Бодрого времени суток.

    А можно при использовании вашего класса реализовать пакетное обновление данных? Используя UPDATE с разными параметрами WHERE?

    Есть 20000 строк и их нужно обновить.

    Если по одному запросу отрабатывать то 1 час уходит.

    Reply
  10. salexdv

    (9) Здравствуйте! Пока такой возможности нет, но попробую реализовать.

    Reply
  11. salexdv

    (9) Добавил два метода. Работа выглядит так:

    MySQL.ОчиститьТекстЗапроса();
    MySQL.ДобавитьЗапрос(«UPDATE product SET price = ’69’ WHERE product_id = 1250»);
    MySQL.ДобавитьЗапрос(«UPDATE product SET price = ‘137’ WHERE product_id = 417»);
    MySQL.ВыполнитьЗапрос();
    

    Чтобы заработало, в настройках соединения необходимо включить «Allow multiple statements» http://take.ms/KOKJR

    Reply
  12. kuril

    для получения данных на лету, в том числе в СКД можно использовать внешний источник данных

    Reply
  13. salexdv

    (12) Можно. Обработка больше для изменения данных в базе, хотя читать её тоже удобно.

    Reply
  14. gospodenkods

    Отличный механизм вышел !! Респект автору.

    Reply
  15. nghleb

    Вручную SSH+ODBC работает отлично. Но при запуске в регламентном задании odbc не видит туннель. Куда копать?

    Reply
  16. salexdv

    (15) Если регламентные задания выполняются на сервере, то у пользователя, под которым работает сервер (по умолчанию USR1CV8X) должны быть настроены источники данных ODBC. Возможно, проблема в этом.

    Reply
  17. nghleb

    (16) Да все верно. Это уже к тому моменту попробовал. Плюс к этому PuTTY тоже нужно настраивать под этим пользователем. Спасибо большое!

    Reply
  18. mort64ram

    Отличный «класс», автор большой молодец, спасибо.

    Reply
  19. maxster545

    соединение через COM в обработке?

    Reply
  20. salexdv

    (19) Да

    Reply
  21. AlenaSa

    Все работает! Спасибо автору!

    Reply
  22. pinkz80

    отличная работа, спасибо!

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *