Прямые запросы к базе 1С на SQL-сервере. Зачем нужно? Насколько оправдано? Как сделать?




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

24 Comments

  1. nomadon

    xxs SQL injection?

    Reply
  2. rk

    Способы борьбы те-же, что и на обычных сайтах. Отключи ошибки и передавай данные, форматированные в нужный тип и нужной длины.

    Reply
  3. A_Max

    (2) Правильный способ это использовать параметры вместо плюсиков.

    А по сути если уж перешли на подключение к БД, то проблему общения тогда лучше было сделать через внешние источники. Создать отдельную базу куда из 1С складывать подготовленные данные и в обратную сторону получать документы для оформления.

    В принципе можно и в базу CMS писать/читать.

    Reply
  4. rk

    (3) «В принципе можно и в базу CMS писать/читать.» Можно и так. Только теряется работа в реальном времени.

    «Правильный способ это использовать параметры вместо плюсиков.» — согласен. Пример приведен в качестве наглядной демонстрации. И плюсиками создается строка html. В реальности, создаются глобальные временные таблицы, а уже из них идет выборка. Причем, в другом соединении. Прямого взаимодействия с таблицами БД 1С нет.

    Reply
  5. A_Max

    (4) Чем же теряется онлайновость если в 1С повесить подписки и в них делать «выгрузку». Ну и в качестве дальнейшего развития я бы вообще на MQ перевёл.

    Reply
  6. rk

    (5)»Чем же теряется онлайновость если в 1С повесить подписки и в них делать «выгрузку». В этом случае не теряется. Тоже можно так. Это даже позволит распределить железные ресурсы под портал, и под базу 1С. Можно даже в другую подсеть вытащить, ради большей безопасности…

    Ну да, раз в сутки остатки обновлять, а потом просто движения добивать. Таблицы маленькие, нагрузка небольшая. Туда-же можно и заказы кидать, чтобы 1С потом забирала и документы создавала. Полная развязка по безопасности, и высокая скорость.

    Reply
  7. asved.ru

    Описанный метод доступа является нарушением лицензионного соглашения 1С.

    Reply
  8. rk

    (7) Сам по себе, метод не может нарушать лицензионное соглашение. Это не решение. Потому, вопросы лицензирования не рассматриваются.

    Reply
  9. asved.ru

    (8) Лицензионное соглашение прямо запрещает именно использование методов, не предусмотренных в сопроводительной документации, для доступа к информационной базе.


    Лицензиат обязуется не допускать нарушений исключительных прав Правообладателя на ПРОГРАММНЫЙ ПРОДУКТ, в частности, не совершать и не допускать совершения третьими лицами следующих действий без специального письменного разрешения Правообладателя:



    осуществлять доступ к информационной базе ПРОГРАММНОГО ПРОДУКТА и построение систем на основе ПРОГРАММНОГО ПРОДУКТА с помощью средств и технологических решений, не предусмотренных в сопроводительной документации;
    Reply
  10. rk

    (9) «Лицензионное соглашение прямо запрещает именно использование методов, не предусмотренных в сопроводительной документации, для доступа к информационной базе. » Ну так не используйте. Я вам не предлагаю решение, нарушающие лицензионное соглашение. И не заставляю вас что-то нарушать.

    По вашей логике, ассемблер запретить надо, т.к. с его помощью можно убрать защиту с программы.

    Reply
  11. DenisCh

    (9)

    осуществлять доступ к информационной базе ПРОГРАММНОГО ПРОДУКТА и построение систем на основе ПРОГРАММНОГО ПРОДУКТА с помощью средств и технологических решений, не предусмотренных в сопроводительной документации;

    MS mamagement Studio описана в документации?

    Reply
  12. rk

    (11) «MS mamagement Studio описана в документации?» — НЕТ.

    Как и не описано, что нельзя выполнять прямой запрос к серверу из той-же 1С-ки.

    Средствами 1С? — Да!

    А уж как я обращаюсь — моё дело.

    Ещё вопрос: зачем выпускается консоль запросов с трассировкой и показом плана запроса?

    Reply
  13. DenisCh

    (12)

    «MS mamagement Studio описана в документации?» — НЕТ.

    То есть архивацию средствами SQL-сервера делать нелья. И создавать базу тоже…

    Reply
  14. man-1982

    Немного не понятна последовательность:

    1. POST-ом с клиента отправляете запрос на веб-сервер 1с.

    2. На сервере 1с обрабатывает запрос.

    3. Преобразуется его в прямой запрос к SQL.

    4. Данные обрабатываем сервером 1с и отправляем клиенту

    Все верно?

    Reply
  15. rk

    (13) Базу предполагается создавать с сервера 1с. А как-уж архивировать, я не знаю…. Видимо, запросом из другой базы 1с:)

    (14)

    1. Можно и на 1с.

    2,3 Предполагается 1 раз НАПИСАТЬ прямой запрос, в который параметрами передавать данные.

    4 Да! Но, с сервера приходит готовый html код.

    Reply
  16. asved.ru

    (10)

    (11)

    Прокурору расскажете.

    На самом деле вы сейчас путаете технологические операции по обслуживанию информационной базы с использованием информационной базы в коммерческих целях в обход механизма лицензирования платформы. Т.е. сколько пользователей у вас заходило на ваш веб-сервер, напрямую работающий с ИБ, столько лицензий вы и украли.

    Думаете, Вы первый догадались, что технически с базой можно общаться и мимо платформы?

    Reply
  17. rk

    (16) — читай (14), (15). Можно пользоваться веб-сервером 1С. Здесь описан метод получения данных с SQL — сервера. При чем здесь лицензирование? Вопрос не по теме.

    Reply
  18. artbear

    Как подзадолбали умники по поводу нарушения лицензионного соглашения.

    Тот факт, что лицензионное соглашение нарушает закон РФ для ПО, не учитываем?

    Это инструменты, в умелых руках полезны, а незнайка может и застрелиться.

    Reply
  19. Reaper_1C

    (13) Внимательно изучите документацию, там все есть:

    https://its.1c.ru/db/v83doc#bookmark:cs:TI000000137

    Reply
  20. rk

    Раз уж подняли вопрос:

    Будет-ли нарушением лицензионного соглашения 1С, если я грохну данные регистра версирования за определенный период, напрямую на SQL-сервере?

    Замечу, что это не обслуживание базы SQL.

    Reply
  21. TODD22

    (20)

    Будет-ли нарушением лицензионного соглашения 1С, если я грохну данные регистра версирования за определенный период, напрямую на SQL-сервере?

    На сколько помню прямая работа с базой через SQL в обход платформы запрещена.

    (18)

    Тот факт, что лицензионное соглашение нарушает закон РФ для ПО, не учитываем?

    Можно подробней что именно нарушает?

    Reply
  22. Nenaviju1C

    (16)

    и прокурору расскажу …

    Повешу службу на IIS со своим веб сервисом и 1Ска будет общаться только с ним, а вот серверная часть службы напрямую с базой на SQL сервере. Что то разве нарушил? 🙂

    Запросы к БД напрямую — это и хорошо и плохо, но все зависит от конкретных задач и от рук, которые пишут интеграцию

    Reply
  23. sinops

    (21) То есть вы хотите сказать, если у меня есть 1С 7.7 SQL версия (торговля) и для руководства у меня написано на 8-ке консоль отчетов, в которой я через внешние данные подключаюссь напрямую с к SQL базе торговли то моя конфа незаконна ?

    Reply
  24. dg15000

    (19)

    Для продолжения работы получите демодоступ или авторизуйтесь

    — можете по русски написать?

    Reply

Leave a Comment

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