<?php // Полная загрузка сервисных книжек, создан 2025-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='\
А где же условия виртуальных таблиц?
Да, спасибо, формирование виртуальных таблиц происходит еще раньше соединений.
Для MS SQLhttps://msdn.microsoft.com/ru-ru/library/ms189499%28v=sql.120%29.aspx
Очень ценный комментарий. Статья будет дополнена.
Есть мнение, что SQL делает так, как ему лучше будет (в соответствии со статистикой). Главное — чтобы результат был таким, какой требует пользователь. Не знаю, как сейчас, но раньше если во временную таблицу вытаскиваешь всю таблицу, а потом агрегируешь ее и берешь оттуда только количество значений, то запрос вообще не выполнялся (на мелкософт скуле по крайней мере).
Статистикой пользуется анализатор запроса и на ее основе выбирает оптимальный план запроса, планы запроса надо читать для разных случаев
Утверждение
Ошибочно. Оператор TOP (ПЕРВЫЕ) выполняется последним (логически), а ORDER (УПОРЯДОЧИТЬ) предпоследним (логически).
(7) tormozit, ИМХО, автор имел ввиду, что топ и ордер выполняются сначала, а агрегирование — потом. Хотя… Понимать — вообще штука сложная. Может на форуме сделать кнопку «Вы уверены, что поняли текст, на который отвечаете. и хотите ответить именно так, как написали?» Какому-то школьнику за это дали вкусных плюшек.
(8) В операторе УПОРЯДОЧИТЬ доступны псевдонимы (результаты) полей оператора ВЫБРАТЬ, в том числе выражений с агрегатными функциями, а также непосредственно в операторе УПОРЯДОЧИТЬ можно указывать выражения, содержащие агрегатные функции.
(8) starik-2005, не надо ерничать. как обработается запрос в реальности зависит и от запроса, и от движка обрабатывающего sql (как обрабатывает запросы же файловая версия 1С, я без понятия).поэтому и есть понятие logical processing order, о котором и написал tormozit. чтобы иметь представления при написании запросов.
https://msdn.microsoft.com/en-us/library/ms189499.aspx
например см
FR OM
ON
JOIN
WH ERE
GROUP BY
WITH CUBE or WITH ROLLUP
HAVING
SEL ECT
DISTINCT
ORDER BY
TOP
т.е. топ вообще на последнем месте.
смотрим запрос автора, но при другой таблице
Показать
Результат будет 1, 37 . т.е. сначала произошло агрегирование и только потом TOP . понятно, что в целях оптимизации в реальности TOP может выполниться сначала. но говорить надо именно о логической последовательности выполнения. там же по ссылке
автор был бы прав в случае если бы указал, что у меня на таком-то сервере, только в этом запросе, в данной таблице, сначала выполняется…и т.д. и то, как у него происходит сначала упорядочивание по агрегатному полю, а потом агрегация, непонятно. но мало ли. может оптимизировалось выполнение так запроса.
Автор не ссылался на планы запросов, оптимизатор и прочее.
Значит в этой теме [возможно] глубоко не разбирался.
А то что он провел исследование и поделился результатами весьма неплохо.
К тому же в основном его выводы верны.
Порекомендуйте коллеге материал для изучения планов запросов, оптимизатора и прочее
и тогда он [возможно] перепишет статью более корректно.
(11) Makushimo, ты не поверишь, но есть БД у которых нет ни оптимизаторов, ни планов
(12) Fox-trot, которые из тех,что использует 1С?
я не ерничаю, а правда кроме SQL ничего и не знаю.
(10) cool.vlad4, Скорее всего, Вы правы: топ на последнем месте. Проверю еще раз, изменю статью. Спасибо.
Воттут майкрософт дает хорошее пояснение:
FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE or WITH ROLLUP // этого в 1с нет
HAVING
SELECT
DISTINCT
ORDER BY
TOP
остается вопрос с «итоги … по …», которые делаются 1сом программно, вероятно это происходит уже с результатом всех операций с БД
(17) Вам лечиться надо.
(16) starik-2005, это тот самый редкий случай , когда starik-2005 знает лучше , что имел в виду автор, нежели сам автор. см.
(13) Makushimo, пусть так, но это все равно не имеет никакого отношения к синтаксису
(12) Fox-trot, оптимизатор запросов есть даже внутри платформы. А еще есть оптимизатор СКД, со своими блекджеками и ш***)))
(22) qwinter, пусть так, но это все равно не имеет никакого отношения к синтаксису )
(23) Fox-trot, этот аргумент ничем не перекрыть :-)) ну просто уложил на обе лопатки.
красава.
(22) qwinter, c преферансом и куртизанками
Статья не имеет никакого отношения к оптимизации и хайлоаду. Это теория программирования в чистом виде.
Потому, что узнать, какие операции и в какой последовательности выполняются в действительности, можно только посмотрев план запроса. Но вот если различный порядок исполнения операций запроса допускает различные результаты, то результат исполнения плана будет логически соответствовать изложенному порядку
Иначе при выполнении
1. Соединение
2. Проверка условия «ГДЕ»
SQL был бы вынужден прочитать все содержимое всех таблиц даже при существовании идеально покрывающих индексов. Вы представляете себе, во что бы вылился запрос чтения, скажем, документа с табличной частью, если их ввведено несколько миллионов?
Фактически SQL первым делом стремится применить имеющиеся условия к исходным таблицам.
Смысла в порядке выполнения TOP вообще никакого нет, он просто прерывает исполнение плана, получив достаточно строк результата.
Не совсем.
Не буду утверждать про все СУБД, но MS SQL если в условии WHERE (ГДЕ) одна из частей условия является константой, а соединение INNER (внутреннее), то движок MS SQL сначала выполняет предварительную фильтрацию таблицы и только потом уже соединение.
(27) Dem1urg, физическое выполнение и «логическое» — немного разные вещи. если результат от разного порядка действий одинаковый — оптимизатор СУБД может извращаться как ему удобно, но логический порядок определен в (15), он не меняется и задается программистом.
(5) starik-2005, ТормозИТ не зря в скобочках написал ЛОГИЧЕСКИ.
Не путайте логическое исполнение и физическое. В статье автор описывает логическое исполнение запросов.
(29) JesteR, Есть нюанс. Оптимизатор может нашаманить план так, что, например, будете ловить деление на 0 или другие арифметические ошибки, хотя «логически» эта строка уже должна быть отфильтрованной. Причем ловить нестабильно от статистики. Но, да, логический порядок обработки программист знать обязан. Но применительно к 1С его ломают дополнительные возможности 1С (которые эмулируются) например:
После них в SQL такой милый фарш иногда выходит, что внятно предсказать (да еще для всех СУБД) могут только астрологи-телепаты (причем с опытом 10+ лет разработки на 1С и SQL)