28.01.2018, 21:33 | #1 |
Участник
|
быстрое удаление товаров
коллеги, может кто-нибудь поделиться кодом или ссылкой на таковой для быстрого удаления товаров InventTable, EcoResProduct и прочих связанных с ними таблиц?
нужно удалить примерно 122 тыщи позиций, так что желательно, чтоб запустить в батче в несколько потоков - есть 4 сервера с 4 ядрами. спасибо!
__________________
Felix nihil admirari |
|
29.01.2018, 08:57 | #2 |
Участник
|
Зачем быстро? Спешка нужна при ловле блох.
Лучше скрыть неиспользуемые позиции, а затем не спеша удалять. Нужно ведь еще проверить что они нигде не используются. |
|
29.01.2018, 09:08 | #3 |
Злыдни
|
Готового нет. Но вот так,вроде, должно сработать:
X++: InventTable _inventTable; EcoResProduct _ecoResProduct; ItemId _itemId; RefRecId _recId; while select forupdate _inventTable { _itemId = _inventTable.ItemId; _recId = _inventTable.Product; if(_inventTable.validateDelete()) { ttsbegin; _inventTable.delete(); ttscommit; } else { info(strfmt("Error delete item %1", _inventTable.ItemId)); } while select forupdate _ecoResProduct where _ecoResProduct.RecId == _recId { if( _ecoResProduct.validateDelete()) { ttsbegin; _ecoResProduct.delete(); ttscommit; } else { info(strfmt("Error delete product %1", _ecoResProduct.DisplayProductNumber)); } } }
__________________
люди...считают, что если техника не ломается, то ее не нужно ремонтировать. Инженеры считают, что если она не ломается, то нуждается в совершенствовании. |
|
29.01.2018, 11:57 | #4 |
Участник
|
А проводки по этим позициям есть? Если нет, то так быстрее будет. Еще можно на SQL запросе - еще быстрее получится.
X++: ttsbegin; inventTable.skipDatabaseLog(true); inventTable.skipDataMethods(true); inventTable.skipDeleteActions(true); delete_from inventTable notexists join inventTrans where inventTable.ItemId == inventTrans.ItemId; ttscommit; |
|
29.01.2018, 12:02 | #5 |
Участник
|
Еще в 5.0 есть класс InventUnusedDimCleanUp. Можно взять за основу, только поменять везде InventDim на InventTable. Там как раз пример построения запроса на SQL.
|
|
29.01.2018, 19:32 | #6 |
Участник
|
таким вот сейчас и пользуюсь, но нужна обёртка для параллельной обработки
__________________
Felix nihil admirari |
|
29.01.2018, 19:34 | #7 |
Участник
|
@Модератор, а где кнопка "Мне не нравится"? ещё лучше бы "Удалить камент как бестолковый"
__________________
Felix nihil admirari |
|
29.01.2018, 20:19 | #8 |
Участник
|
именно это и надо! где взять?
__________________
Felix nihil admirari |
|
29.01.2018, 20:29 | #9 |
Участник
|
В смысле? Создать. Чего сложного-то? Как-то ведь 122 тысячи позиций указываете. Неужели константами в джобе? Ну, так вместо констант создать табличку и в нее загнать все 122 тысячи значений
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
29.01.2018, 20:33 | #10 |
Участник
|
Как вариант, можно привязать удаляемые номенклатуры как каким-нибудь особым веткам классификатора. И отдельные пакетники каждый по своей ветке
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
29.01.2018, 20:39 | #11 |
Участник
|
в исходном топике не было вопроса "как?", там была просьба поделиться готовым кодом.
сложного то, что времени нет
__________________
Felix nihil admirari |
|
30.01.2018, 00:03 | #12 |
Участник
|
Создать таблицу со списком удаляемых позиций, например InventTableCleanUp, дальше примерно так:
X++: InventTable.skipDataMethods(true); InventTable.skipDeleteActions(true); InventTable.skipDatabaseLog(true); InventTable.skipEvents(true); delete_from InventTable exists join InventTableCleanUp where InventTableCleanUp.ItemId == InventTable.ItemId ; |
|
30.01.2018, 00:42 | #13 |
Участник
|
Может есть еще какой-то критерий, по которому можно отсортировать записи? Например, я удалял данные из неактуальных компаний (наследие предков) таким вот кодом
X++: protected void deleteAllNotCurCompany() { str sqlStr; Dictionary dict = new Dictionary(); SysDictTable dictTable; tableId tableId; int64 recordCount, recordSum, tableCount; Common common; Connection connection = new Connection(); SqlSystem sqlSystem = new SqlSystem(); Statement statement; int i; ; progressBar.setText(strfmt("Удаляю таблицы неактуальных компаний (%1) ...", dict.tableCnt())); progressBar.setTotal(dict.tableCnt(), 2); for (i=1; i<=dict.tableCnt(); i++) { progressBar.incCount(1, 2); tableId = dict.tableCnt2Id(i); dictTable = new SysDictTable(tableId); if (!dictTable || dictTable.isMap() || dictTable.isTmp() || dictTable.isView() || !dictTable.dataPrCompany()) continue; common = dictTable.makeRecord(); common.disableCache(true); while select crosscompany count(RecId) from common group by dataAreaId { recordCount = common.RecId; if (recordCount && !this.isInCurCompany(common.dataAreaId)) { sqlStr = 'DELETE FROM ' + dictTable.name(DbBackend::Sql); sqlStr += ' WHERE (' + dictTable.fieldName(fieldnum(common, DataAreaId),DbBackend::Sql); sqlStr += ' = ' + sqlSystem.sqlLiteral(common.dataAreaId) + ') '; connection.ttsbegin(); statement = connection.createStatement(); new SqlStatementExecutePermission(sqlStr).assert(); statement.executeUpdate(sqlStr); connection.ttscommit(); CodeAccessPermission::revertAssert(); recordSum += recordCount; tableCount++; } } } info(strfmt("Удалено %1 записей в %2 таблицах неактуальных компаний", recordSum, tableCount)); } X++: //BAH Да, если компания текущая или виртуальная в текущей private boolean isInCurCompany(DataAreaId _dataAreaId) { ; if (this.getCompanyFromVirtual(_dataAreaId) == curExt()) return true; return false; } X++: //BAH186 26.01.2018 Возвращает первую попавшуюся компанию, входящую в состав виртуальной private DataAreaId getCompanyFromVirtual(DataAreaId _virtual) { VirtualDataAreaList virtualDataAreaList; ; if (this.isVirtual(_virtual)) { select firstonly virtualDataAreaList where virtualDataAreaList.virtualDataArea == _virtual; return virtualDataAreaList.Id ? virtualDataAreaList.Id : ""; } else return _virtual; } X++: //BAH186 Да, если компания виртуальная private boolean isVirtual(DataAreaId _dataAreaId) { DataArea dataArea; boolean ret; ; select firstonly id from dataArea where dataArea.id == _dataAreaId && dataArea.isVirtual == NoYes::Yes; if (dataArea) { ret = true; } return ret; } ) за 1-2 часа (точнее не засекал, отслеживал каждый шаг в дебаггере). И то на тестовой базе, которая в 3-5 раз медленнее рабочей.
__________________
Я прибыл к вам из Кантемировской дивизии. А там, как известно, дураков не держат! |
|
02.02.2018, 18:59 | #14 |
Участник
|
__________________
Felix nihil admirari |
|
|
За это сообщение автора поблагодарили: Logger (3), Vadik (1). |
Теги |
batch, inventtable, multithreading, полезное, удаление |
|
Похожие темы | ||||
Тема | Ответов | |||
Отображение распаковки, запаковки и переупаковки товаров | 9 | |||
Удаление товаров | 4 | |||
Группы товаров. | 4 | |||
Удаление проекта | 0 |
|