Связи Метаданных. Построитель 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='\

23 Comments

  1. German

    Зачем Datagrid если есть GamewithFire

    http://main.1c-ei.ru/Articles/gamewithfire/properties-1

    Reply
  2. shishkin1966

    (1) а зачем он нужен ? Можно тащить результат из RecordSet во что угодно. Можно тащить в обычное табличное поле (я не стал этого делать, чтобы убрать преобразование типов RecordSet -> 1C). Кому нужны суррогатные ключи 1C ? Важны связи между таблицами, а не представление суррогатных ключей. Цель этой обработки — создание Query Analyzer для 1С. Когда работаешь с БД, важно не наличие каких-то сущностей, а их связи друг с другом.

    Reply
  3. German

    а как же параметры запросов 😀

    Reply
  4. shishkin1966

    (3)

    в Query Analyzer все параметры указываются ручками. Даже списки. А писать условие по типу Where ID = 2247623874356 или Where ID in (2463296,2452845) это дурной тон в разработке !!! (потому что прийдя через месяц никак не узнать почему ID = 348539 или 85674976) — таких примеров можно увидеть у Диасофта — там такого добра хватает. У нормальных разработчиков пишется (разве сложно написать ?)

    T1 join T2 on t1.id = t2.id where t2.Фамилия in («Шишкин»,»Пупкин»,»Фыфкин») или

    T1 where T1.ID = (select max(ID) from T2 where Фамилия = «Шишкин»)

    Reply
  5. shishkin1966

    доработан вызов ADO, для обработки таких запросов:

    sp_executesql

    N’with Номенклатура(Level,_Description, _ParentIDRRef) as

    (Select

    1 as Level

    ,_Reference4._Description

    ,_Reference4._IDRRef

    From _Reference4

    Where 1=1

    and convert(int,_Reference4._ParentIDRRef) = 0

    union all

    Select

    Level + 1

    ,_Reference4._Description

    ,_Reference4._IDRRef

    From _Reference4

    join Номенклатура on _Reference4._ParentIDRRef = Номенклатура._ParentIDRRef

    )

    select Level,_Description as »Наименование» from Номенклатура


    Reply
  6. Трактор

    Только для MS?

    Reply
  7. shishkin1966

    я могу еще под Oracle, только не знаю на какую версию он встанет. У меня есть 9.2/10.

    Под Linux (PostGreSQL) ничего не писал. Даже Unux не ставил :cry:, а надо бы

    Reply
  8. shishkin1966

    А что интересно ?

    Reply
  9. shishkin1966

    а так он писан через вызов ADO, а там какой провайдер укажешь — к тому и зацепишься.

    Reply
  10. shishkin1966

    Дополнения:

    — Расширил вывод информации о связи в тексте запроса

    Reply
  11. shishkin1966

    Дополнения:

    — обработка задач

    Reply
  12. shishkin1966

    Дополнения:

    — для серверов MS SQL добавлена возможность просмотра плана запроса

    Reply
  13. shishkin1966

    Дополнения:

    — добавлена вставка по возможности синонимов 1С в текст запроса. Режим поля «Подставлять заголовки» = «Брать из Метаданных все»

    Reply
  14. zzz_natali

    При запуске обработки заполняется только левая часть формы «Текст запроса и результат». правая часть остается пустая. Где и чем помыть руки? Спасибки…

    Reply
  15. shishkin1966

    (14)

    Данный построитель аналог программы Query Analyzer фирмы Microsoft для MS SQL 2000. Это главный инструмент разработчика запросов к БД от MS. Ваша задача построить запрос в текстовом виде. Для этого просто перетягиваете таблицы (колонки) из дерева таблиц на основное поле, или это же самое проделываете с деревом связей таблиц 1С. Построив запрос вы затем просто его выполняете — нажимая кнопку «Выполнить запрос» и анализируете полученный результат. Все просто и гениально. Если надо задать параметры — строите условие WHERE. Только среди разработчиков SQL считается дурным тоном строить вот такие условия

    Select * from Table1 Where ID = 23424532523, что равносильно запросу 1с: Выбрать * ИЗ Номенклатура ГДЕ Номенклатура = &Номенклатура_Ссылка;

    Для рисования запросов можете использовать любимый программерский редактор — у меня это EditPlus. Он удобный, шустрый и подсвечивает красиво.

    Или вам нужен визуальный построитель?

    Reply
  16. zzz_natali

    (15) Гениально было бы об этом написать в предварительном описании Вашей обработки! 🙂

    Или Вы блондинофоб? 😉

    (блондинофоб — здесь: человек, ненавидящий особей женского пола со светлым типом волос)

    Спасибо.

    Reply
  17. shishkin1966

    А вы в текстовом виде когда — нибудь писали запросы или всегда пользуетесь построителем запроса ?

    Просто ни один из разработчиков БД, которых я знаю, не пользуются никакими визуальными построителями запросов. Все набирают текст в обычных текстовых редакторах и посылают их на выполнение. У них никогда не возникали вопросы, а почему правое поле пустое, будь это Oracle Developer или Query Analyzer. Для них только нужен список таблиц,VIEW(и их колонок) и описание связей между таблицами и все.

    Reply
  18. shishkin1966

    Добавлено:

    — поддержка вывода результатов нескольких Select’ов в одном запросе

    Reply
  19. shishkin1966

    Добавлено:

    — запуск на выполнение выделенной части текста

    Reply
  20. pizhenkov

    {Форма.Форма.Форма(2242)}: Поле объекта не обнаружено (СвязиМетаданныхПостроительЗапросаSQL)

    Форма = Обработки.СвязиМетаданныхПостроительЗапросаSQL.ПолучитьФорму(«Connect»);

    При открытии в УТ 10.3 (1С:Предприятие 8.2 (8.2.18.109))

    Reply
  21. shishkin1966

    (20) pizhenkov,

    я больше не поддерживаю 1С — раньше все работало — теперь все вопросы к ним. Если они меняют доступ к объектам даже в пределах одной подверсии — слов нет. Все работало вроде до версии 8.2.13 — дальше все было вырезано. Лазил по форумам — ничего не получилось. Спросите у знающих 1с — как открыть модальную форму внешней обработки.

    Reply
  22. realchel

    А что в этом файле?

    Transact-SQL Reference (MS SQL).

    Postgre SQL Reference (Postgre SQL).

    Reply
  23. shishkin1966

    (22) realchel,

    Описание языков программирования БД

    Reply

Leave a Comment

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