<?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='\
Действительно, стоит добавить запрос в пакет и надо перенумеровывать выборки в коде и потом заново отлаживать.
Ах да, естественно, имя результата должно удовлетворять нотации имён переменных в 1С.
Я так понимаю, любое неосторожное использование конструктора запроса затрет эти имена таблиц, не помню только в 1С добавил поддержку комментариев в конструкторе или нет, но идея интересная.
(3) karpik666, затрёт, конечно. Но подобные монструозные запросы уже и не рассчитаны на конструктор. Они собираются по частям, иногда в разных блоках кода, изобилуют нечитаемыми для конструктора кусками, и потому… Терять особо нечего.
Конструктор запроса из подсистемы «Инструменты разработчика» не затрет такие комментарии.
Для тех, кто имеет доступ на партнерский форум 1С, приведу ссылку на одну из тем где это обсуждалосьhttps://partners.v8.1c.ru/forum/topic/1182939
Думаю скоро это добавят в платформе.
(6) tormozit, ага, оно самое. Приятно, что не мне одному сие показалось неудобно; спасибо за ссылку.
Честно говоря, вообще впервые имел дело с большим пакетным запросом, раньше как-то везло. А тут… Не вынесла душа поэта))
(6) tormozit,
Из топика по ссылке таких выводов сделать нельзя…
(4) круто, а ведь наверное можно «идентификатор» результата в пакете поместить не как комментарий, а в виде фиктивного поля в выборке в самом запросе:
…
;
ВЫБРАТЬ
«МояНужнаяВыборка» КАК IDРезультат,
Крайние.Виновник.Фамилия,
Крайние.Виновник.Адрес …
или
…
0 КАК ID_МояНужнаяВыборка,
…
Ну и доработать функцию, которая строит соответствие. Плюс в том, что эта конструкция не затрется, а минус в том, что дополнительное поле не должно повлиять на сам конечный результат вопроса, но оно вроде в большинстве случаев и не повлияет.
(9) konstruktiv, ну тогда уж лучше фиктивная выборка. Никаких минусов и данных хранить в ней можно сколько душе угодно.
Показать
(10) Патриот, не, тогда уж лучше так
Показать
А потом
Показать
Ну это если без проверок. )))))
Ну раз супруга сказала…) Мне пригодиться, спасибо!
(10) Патриот, тогда при редактировании запроса в конструкторе придется следить за положением запросов для идентификации результатов, быть особенно аккуратным при изменении места запроса в очереди, которая в конструкторе выглядит просто «запрос1/запрос2/…/запросN».
(11) PrinzOfMunchen, что-то я не разобрался спросонья, получается в последнем запросе опять же нужно вручную указать где какой результат, и при редактировании исходного запроса следить, чтобы эти места соответствовали реальным — от чего и хотел избавиться автор публикации?
(14) konstruktiv, да. ) Но это так, в порядке бреда, в ответ на пост (10).
А вообще, за всю свою насыщенную 1С-кой жизнь, не натыкался на такой уж огромный запрос, который надо настолько часто редактировать, что можно забить на производительность и пойдя на поводу лени написать такую функцию, вместо того чтобы один раз указать индексы.
Может быть, в каждый выходной запрос добавить поле как идентификатор очередного результата?
(16) МимохожийОднако, см. 9)
В следующей версии подсистемы «Инструменты разработчика» будет широкая поддержка имен запросов и частей объединений.
Я обычно пишу:
последний результат запроса:
Предпоследний:
и т.д., так меньше вероятность словить ошибку, чем если с начала считать, т.к. новые пакеты обычно перед результирующими добавляются и нумерация с конца не сбивается. И с конца в любом случае проще считать.
Сегодня наткнулся на такой запрос. Его же сложно понять, в чем специфика? Скорость?
(20) Xershi,
В том что ты читаешь данные один раз. И возвращаешь результаты нескольких запросов за один раз. А не выполняешь трижды(или сколько у тебя пакетов) чтение из базы.
(21) TODD22, т.е. только скорость и не более?
(22) Xershi, Уменьшение количества обращений к базе.
(20) Xershi, в базовом функционале последних версий типовых пакетный запрос часто используется для сборки всех движений, Но там грамотно сделано, а не как у автора заметки — там используются функции, возвращающие текст запросов, которые в итоге объединяются в один пакет и за раз отправляются на сервер. Обычно первая часть запроса — это временные таблицы, в которые выбираются ТЧ документа и прочие нужные параметры.
Лично я так бы делать не стал, как в статье описано.
У меня в консоли запросов есть парсинг по именам таблиц может пригодится,сделал для упр форм тоже,раньше были только обычные формы.http://infostart.ru/public/64616/
На платформе 8.3.8
Во время отладки запросов реализована возможность работы с временными таблицами: просмотр списка временных таблиц, структуры временных таблиц и содержимого временных таблиц.
Реализован метод Запрос.ВыполнитьПакетСПромежуточнымиДанными(). Реализовано свойство МенеджерВременныхТаблиц.Таблицы.
В версии 3.61 подсистемы «Инструменты разработчика» реализовано:
Консоль запросов
+Реализовано чтение имен запросов и частей объединений при построении дерева запроса
+Над таблицей результата пакета добавлен флажок «По именам» для вывода только именованных элементов
+Добавлен параметр мРезультатПоИменам обработчика результата для доступа к именованным элементам результата пакета
Конструктор запроса
+Реализована возможность присвоения имен запросам и частям объединений с чтением и сохранением их в комментариях
Пример текста запроса:
Показать
На скриншотах показан вид этого текста в дереве запроса консоли запросов и конструкторе запросов.
Пример кода:
(6)
Думаю скоро это добавят в платформе.
чёто прошло два с половиной года, а воз и ныне там.
Автору спасибо и плюс, полезная фишка.