Быстрое удаление документов (только для SQL)




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

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

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

<?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='\

56 Comments

  1. tsd

    последняя фраза на мой взгляд все убивает. Ибо простым нажатием кнопки мы легко можем похезить целостность базы

    Reply
  2. PowerBoy

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

    Reply
  3. vit1c

    Так если удалять документ, то и движения все удаляются (лениво код смотреть)

    Reply
  4. PowerBoy

    (3) Конечно!

    Reply
  5. Ugrumi

    У меня сразу ошибку показала!!!

    Reply
  6. PowerBoy

    (5) Какая ошибка? Текст пожалуста и версии платформы, конфигурации и SQL servera.

    Reply
  7. Ugrumi

    Ошибка в закладке обработка в таб. части. Имя документа + ошибка. УПП 1.2.17.3, Microsoft SQL Server Management Studio 9.00.1399.00.

    Reply
  8. PowerBoy

    (7) Можно дословный текст ошибки в кавычках?

    Reply
  9. Ugrumi

    В копии вроде работает, в рабочей проверять уже не буду!

    Reply
  10. DllloKeP

    Отличная обработка, но пришлось подправить из-за 2 возникающих ошибок:

    1) Некорректный перевод даты (если её выбирать в условии). SQL воспринимает: гггг.мм.дд, а переводилось в дд/мм/гггг.

    2) В обработке в таблице _SequenceChangeRec выбиралось поле _Recorder_RRRef, а надо было _RecorderRRef.

    Reply
  11. MAP5

    Чистил базу, перед обновлением конфигурации, и вводом начальных остатков, даже часть документов оставлял в базе, на удивление даже не пришлось перебрасывать в идентичную конфигурацию. Заработала на живую. Пробовал на торговле (2 часа на все) и Бухгалтерии (12 часов)

    Reply
  12. PowerBoy

    (11) У меня бухгалтерию в 10 Гб вычищает за чуть больше часа.

    у Вас 12 часов — это какой размер базы? или сервер слабый?

    Reply
  13. MAP5

    Бухгалтерия 4 года, сеть магазинов розница, количество маленькое, но строк много.

    У меня перепроведение докуметов за ночь (с 18 по 09) успевает только один месяц. Прирост в год больше 10 Гб. Потому и открывал заново, что база уже не ворочается. Выгрузка DT занимала полтора часа.

    Reply
  14. finvest

    За обработку спасибо. В процессе использования сделал два уточнения:

    1. Учёл смещение дат в sql-базе для пересчета значения даты в параметре.

    2. При удалении последовательностей изменил запрос для указания ссылки на реквизит регистратора в трёх вариантах сразу (действует всегда только один):

    _Recorder_RRef

    или

    _RecorderRRef

    или

    _Recorder_RRRef

    Reply
  15. lda0312

    Не работает, не может получить кол-во документов, все время 0, что делать?

    Reply
  16. Alav

    (15) Какая платформа, какой скуль?

    Reply
  17. lda0312

    (16) (8.2.13.218), sql 2005

    Reply
  18. Alav

    (17) Подключаться нажимали? Окошко с параметрами выскакивала? Параметры правильно указываете, т.е. тест соединения проходи?

    Reply
  19. lda0312

    (18)Да все подключается, без ошибок

    Reply
  20. lda0312

    Получилось выполнить удаление только на платформе 8.1, на 8.2 не находила документы, возможно причина была в том что 8.2 работает не по стандартному порту 1541 а по 2041. При удалении на 8.1 дико рос лог и обработка падала с ошибкой, указал ограничение логу в 20 Гигов, хватило и все прошло успешно.

    Reply
  21. anna_irk

    просто удаляет? или позволяет перецепить данные документы

    Reply
  22. PowerBoy

    (21) да

    Reply
  23. ELInfinito

    Очень полезно и своевременно.

    Только пришлось реализовать ссылочную целостность и добавить возможность удаления документов списком.

    Спасибо!

    Reply
  24. Murom

    Работает как часы. Меня очень сильно выручила.Базу с 40Gb до 5Gb урезал очень быстро(по сравнение с типовым удалением).

    Только была проблема с отбором документов по периоду. Неверный формат преобразования дат в формат sql: у меня почему-то дата вот-так «2011-06-17». Если б еще автоматически определяло формат дат sql сервера. 🙂 Хотя можно и без этого.

    Reply
  25. EugeneMIPT
    ELInfinito пишет:

    Очень полезно и своевременно.

    Только пришлось реализовать ссылочную целостность и добавить возможность удаления документов списком.

    Спасибо!

    Поясните пожалуйста, что конкретно имеется в виду под реализацией ссылочной целостности? Замена во всей конфигурации ссылок на удаляемые документы — пустой ссылкой?

    Reply
  26. LoboVik

    Подключаюсь к базе. Задаю на удаление один вид документов «АвансовыйОтчет», устанавливаю отбор за период выдает пустую ошибку.

    Reply
  27. LoboVik

    Да… База на 8.2 платформе.

    Reply
  28. Banzai79

    У меня вопрос после очистки документов, в центральной базе удаляться ли в периферийной базе после обмена данных?

    Reply
  29. Banzai79

    скачал вашу обработку, но выдает ошибку при проверить соединение… текст ошибки

    «Не выполнена проверка соединения из-за ошибки при инициализации поставщика. Неопознанная ошибка», в чем дело?

    Reply
  30. Banzai79

    спс все быстро удаляет, с ошибкой разобрался надо было подключаться через поставщика SQL Native Client и там указать имя сервера и стандартный пользователь sa

    Reply
  31. Banzai79

    теперь проверяю будет ли удаляться в периферийной базе кому будет интересен результат тому отвечу

    Reply
  32. Banzai79

    Спасибо большое автору хорошая обработка тем кому надо обрезать большую базу. Но жаль что не передается через обмен на периферийную базу. (РИБ 1С 8.1.15.14 управл торг для Казахстана 2.2.8.10)

    Reply
  33. Banzai79

    после очистки базы этой обработкой у меня размер SQL базы не уменьшилось, в чем дело?

    Reply
  34. VanechkaDiev

    а на PostgresSQL не работает что — ли?

    Reply
  35. GANR

    Идея хороша, но сыро пока — куча не обнаруженных объектов по ссылке вывалилась после выполнения обработки при тестировании и исправлении.

    Reply
  36. SeiOkami

    (26) LoboVik, такая же ошибка…

    Автор, ты где?

    Reply
  37. ortpro

    Не работает отбор по дате!!! Выбираю все документы, в отборе указываю период для отбираемых документов — удалено документов 0!!! Из-за этой обработки купил подписку за 800!!! р. На#рена нужен аватар для публикации комментариев???!!!!

    Reply
  38. ortpro

    (36) SeiOkami, в бегах, видимо )))))

    Reply
  39. SeiOkami

    Не знаю как отбор, а вот ошибка, что на скрине в (26) решается коментированием в коде обработки участка удаления последовательности документов (если не путаю, просто давно пару месяцев назад ей пользовался).

    Reply
  40. SeiOkami

    ну как решается… по крайней мере так работать будет =)

    потом последовательности можно своим кодом очистить

    Reply
  41. softacademy

    подскажите что нужно подправить в обработке чтоб под 8.2 отбор по периоду работал sql2008r2

    Reply
  42. angy

    На 8.2 один документ удаляла 5 мин, дальше не стал ждать, лажа какая то 🙁 ….

    Reply
  43. rustamsmax

    очень полезная штука.. спасибо..

    Reply
  44. vadimlp77

    На 8.2 не работает. Что сделать ? И кстати если условий несколько — текст запроса формирует некоректно, пришлось пробел добавить перед «И»

    Reply
  45. a1ex4ndr

    (42) В документе не война и мир были? а то может еще и быстро удалилось…

    Reply
  46. quick

    пробую почистить базу в 140 ГБ БП 2.0 🙂 последняя надежда.

    Reply
  47. 7OH

    (46) quick, Вышло ?

    Есть желание удалить ПРОВОДКИ по определенныйм документам с базе на 700 Гиг.

    Обработка ПРОВОДКИ умеет удалять ?

    Почему справшиваю — нарисовал запрос в SQL на удаление из основной таблицы — в надежде что из таблицы ЗначенияСубконто данные удалятся сами (триггерами).

    Как оказалось 1С об этом не подумала.

    Теперь вопрос — пытаться догадаться как именно связаны две таблицы (ключа в таблицах нет) или это может сделать эта обработка ?

    Reply
  48. Serg O.

    Условие ДоговорКонтрагента.Наименование «Содержит» — преобразует в Like…

    имя поля через точку — надо бы добавить замену имени параметра через _

    но почему то SQL запрос не cработал

    Reply
  49. serg1974

    Здравствуйте! Кто может описать какие подводные камни есть при удалении напрямую? где то это обсуждалось?

    Очевидно что надо удалять корректно — т.е.

    1) не удалять документы — т.к. там не только документ + табл части в разных таблицах SQL но и еще есть движения регистров и общие итоги! Вывод лучше не связываться с удалением документов!

    2) удаление справочников — тут уже проще — надо лишь убедиться что на удаляемые элементы не осталось ссылок в других объектах базы.

    3) удаление данных регистра сведений — совсем просто, но они и штатными средствами неплохо чистятся!

    Вопрос:

    Что то еще я не учел? Итоги или общие данные базы какие то? Все ли я верно написал в пунктах?

    Reply
  50. mihey

    Скачал, попробовал, не учитывает смещение в 2000 лет, но лечится без вмешательства в код, просто добавьте 2000 лет к дате в отборе

    Reply
  51. trio-tlt

    Клевая обработка. Хорошо написана — при желании можно легко дописать то, что нужно тебе.

    Reply
  52. GERDUSKA

    Добрый день! Подходит ли обработка для базы на postgre sql?

    Reply
  53. Xershi

    (49) суть удаления через скуль скорость!

    Но вы должны быть экспертом и все эти пункты просчитать иначе привет базе))

    В каком месте может вылезти ссылка на объект? Нужно в каждом случае рассматривать, что вы хотите удалить, а то что вы описали это только часть айсберга может быть.

    О чем я говорю? Прогнать все метаданные, не только то что на поверхности, тогда и будет результат на лицо!

    Reply
  54. GERDUSKA

    Подскажите, какие параметры подключения к базе posgre указывать в обработке

    Reply
  55. PowerBoy

    (54) На Postgre не проверял, возможно придется код править.

    Reply
  56. alexkm82

    При установлении отбора выдавало что удалено 0 документов, добавил к дате (к году) 2000 и все получилось.

    Reply

Leave a Comment

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