01.02.2010, 13:59 | #1 |
Участник
|
Как отследить все факты создания таблиц при постинге?
Мне нужно знать в какие таблицы создаются записи при постинге (например FreeTextInvoice). Не очень хочется отслеживать каждую строчку кода.
Пробовал с Профайлером: - открыл профайлер - запустил Start - FreeTextInvoices ==> Posting (успешно завершен) - профайлер Stop - смотрю результаты (и хочу увидить вызовы insert методов) - но нет ничего похожего Подскажите, что не так или как можно быстро узнать все таблицы создающиеся при Посте. Спс Последний раз редактировалось andriy_s; 01.02.2010 в 14:02. |
|
01.02.2010, 14:20 | #2 |
Участник
|
А вы с какой целью интересуетесь? Случайно, не ради ли Удаление разнесенного складского журнала.?
|
|
01.02.2010, 14:22 | #3 |
Участник
|
Если Вы работаете на Oracle, то можно воспользоваться тригером на таблицу вида:
create or replace trigger имя_тригера before delete on имя_таблицы for each row declare begin пишем в лог или еще куда-нибудь end имя_тригера Здесь я перекрыл before delete можно также criate и т.д. |
|
|
За это сообщение автора поблагодарили: Gustav (2). |
01.02.2010, 15:46 | #4 |
Участник
|
1. Берете тестовую базу, чтобы кроме вас там никто не работал
2. входите в Аксапту 3. выполняете в SQL Server Management Studio запрос "DBCC showcontig with tabletesults" - получаете список всех таблиц с числом записей в них 4. делаете разноску 5. повторяете пункт 3 6. сравниваете результаты запросов до и после - получаете список изменившихся при разноске таблиц. Немного долго, зато железно. |
|
|
За это сообщение автора поблагодарили: mazzy (2), alex55 (1), driller (1), Proba (1), andriy_s (1). |
01.02.2010, 16:02 | #5 |
MCTS
|
|
|
|
За это сообщение автора поблагодарили: Zabr (1). |
01.02.2010, 16:27 | #6 |
Moderator
|
Неоднократно занимался подобной штукой в одиночестве на тестовой базе (Zabr абсолютно прав! ), причем, последний раз не так давно - 16.12.2009, как следует из условия в while select (см. в джобе). После постинга пробегался по всем таблицам Аксапты, имеющим записи и запоминал из них несколько (например, 200) самых последних по RecId. Дальше выгружал в Excel, сортировал по RecId и смотрел записи в районе тех RecId, в которых я был уверен, что они относятся к исследуемой операции (обычно известны RecId ранесенных записей из LedgerTrans). Пару раз обнаруживал таблицы, о которых откровенно не знал, что они задействованы при данной операции!
Вот мой джоб: X++: #CCADO #define.rowLimit( 200 ) static void Job235_whereRecId(Args _args) { Dictionary dictionary = new Dictionary(); TableId tableId; DictTable dictTable; Common common; COM rst, flds, fld; int row, i, timeStart; ; timeStart = timenow(); rst = AdoRst::openRecordsetInMemory([ ['TableId' , #adInteger ], ['TableName' , #adVarChar ], ['RecId' , #adInteger ]]); flds = rst.Fields(); // цикл по таблицам for (i=1; i<= dictionary.tableCnt(); i++) { tableId = dictionary.tableCnt2Id(i); dictTable = new DictTable(tableId); print strFmt('%1 -- %2', tableId, dictTable.name()); // если в очередной таблице нет записей // то переходим к следующей if (! new SysDictTable(tableId).recordCount()) continue; common = dictTable.makeRecord(); row = 0; // цикл по последним записям таблицы while select common order by RecId desc where common.createdDate == 16\12\2009 && common.createdBy == 'MNY' { row++; if (row > #rowLimit) break; rst.AddNew(); fld = flds.Item(0); fld.Value(tableId); fld = flds.Item(1); fld.Value(dictTable.name()); fld = flds.Item(2); fld.Value(common.RecId); rst.Update(); } } AdoRst::sendRecordsetToExcel(rst); info(strfmt('Время выполнения: %1 сек', timenow()-timeStart)); } * Метод openRecordsetInMemory можно взять в моем блоге: http://axforum.info/forums/blog.php?b=60 * Метод sendRecordsetToExcel имеет следующий вид (и к нему еще внутри - deleteFilteredRecords): X++: // Created on 06 Ноя 2008 at 16:26:03 by KKU // выводит в Excel переданный ADODB.Recordset (обычно это disconnected recordset в памяти) // если записи выводятся на несколько листов, то рекордсет в процессе вывода "ломается" // за счёт удаления уже выведенных в Excel записей // возвращает false, если удалений записей не было (т.е. всё вывелось на один лист и рекордсет остался нетронутым) // или true - если были удаления (rstWasChanged) static boolean sendRecordsetToExcel( COM _rst, int _maxRows = 65000, int _maxColumns = 0) { COM xlApp = new COM('Excel.Application'); COM wbks = xlApp.Workbooks(); COM wbk = wbks.Add(); COM wkss = wbk.Worksheets(); COM wks; COM rng; COM cell; COM column; COM rngCols; COMVariant columnWidth; COM flds = _rst.Fields(); int i; // разобраться здесь _maxColumns- то считается с единицы int iMax = (_maxColumns) ? (min(_maxColumns,flds.Count())) : flds.Count(); int sheet = 1; #CCADO ; // раз уж CopyFromRecordset, как выясняется, выводит без фильтра, // то на всякий случай еще и принудительно их удалим (а то вдруг починятся когда-нибудь у Microsoft) _rst.Filter(''); _rst.Sort(''); while (true) { // добавляем лист, если нужно if (sheet > wkss.Count()) wkss.Add(COMArgument::NoValue, wkss.Item(wkss.Count())); wks = wkss.Item(sheet); wks.Activate(); // для отображения ДАТЫ как ДАТЫ на 2-м и 3-м существующих листах // выводим строку имен полей (1-я строка листа Excel) rng = wks.Range('A1'); for (i = 1; i <= iMax; i++) { cell = rng.Offset(0, i-1); cell.Value2( COM::createFromObject( flds.Item(i-1) ).Name() ); } rng = rng.CurrentRegion(); COM::createFromObject( rng.Font() ).Bold(true); // делаем выведенные заголовки жирным шрифтом // выводим данные, начиная со 2-й строки листа Excel rng = wks.Range('A2'); if ( !(_rst.BOF() && _rst.EOF()) ) // если есть записи { _rst.MoveFirst(); if (_maxColumns) rng.CopyFromRecordset( _rst, _maxRows, _maxColumns ); else rng.CopyFromRecordset( _rst, _maxRows); } // подгонка ширины колонок (с ограничением не более 35) rng = rng.CurrentRegion(); rngCols = rng.Columns(); COM::createFromObject( rngCols.EntireColumn() ).AutoFit(); for (i = 1; i <= iMax; i++) { column = COM::createFromVariant( rngCols.Item(i) ); columnWidth = column.ColumnWidth(); if (columnWidth.double() > 35) column.ColumnWidth(35); } // здесь накручено, чтобы не пользоваться RecordCount // -------------------------------------------------- // попытка достичь конца файла, продвинувшись от начала на количество выведенных записей // у нас это кол-во всегда одно - _maxRows, так как мы удаляем записи на каждом шаге // точнее ПОСЛЕ каждого (поэтому, если лист один, то рекордсет сохраняется в первозданном виде) if (!_rst.EOF()) _rst.Move(_maxRows, #adBookmarkFirst); // если вдруг конец файла уже был достигнут ранее, то его обработает следующий оператор if (!_rst.EOF()) { AdoRst::deleteFilteredRecords(_rst, _maxRows); sheet++; } else { break; // иначе завершаем цикл вывода на листы } } xlApp.Visible(true); if (sheet > 1) return true; // rstWasChanged - если листов более одного, то исходный рекордсет не сохранен else return false; } /* Удаляет "видимые" записи из текущего рекордсета. Если рекордсет был отфильтрован, то будут удалены только записи, соответствующие фильтру. Можно задать удаление не всех отфильтрованных записей, а только несколько первых (_numRecords > 0). В этом случае имеет смысл перед удалением применить сортировку, чтобы гарантировать определенный порядок удаляемых записей. */ static int deleteFilteredRecords(COM _rst, int _numRecords = 0) { int affectedRecords = 0; int i; void deleteOneRecord() { affectedRecords++; _rst.Delete(); _rst.MoveNext(); } ; if (_rst.BOF() && _rst.EOF()) return 0; // если набор пуст - выходим _rst.MoveFirst(); if (_numRecords) { for (i=1;i<=_numRecords;i++) { if (!_rst.EOF()) deleteOneRecord(); else break; // если _numRecords больше реального числа записей } } else { while (!_rst.EOF()) deleteOneRecord(); } _rst.MovePrevious(); /* так надо, так как после последнего удаления указатель находится за последней записью (EOF=true), но при этом BOF=false - так вот для этой коррекции и надо, чтобы стало и BOF=true, и EOF=true если же в наборе остались записи, то это действие поставит указатель на последнюю запись */ return affectedRecords; // кол-во удаленных записей } Последний раз редактировалось Gustav; 01.02.2010 в 16:30. |
|
|
За это сообщение автора поблагодарили: mazzy (2), alex55 (1), Proba (1), andriy_s (1). |
01.02.2010, 16:44 | #7 |
NavAx
|
До операции включаем.
Сервис\Параметры\SQL\Мониторинг запросов SQL\Множественные запросы SQL\Вывод в файл После выключаем и анализируем файл. Файл лежит в подкаталоге Log рядом с приложением. |
|
|
За это сообщение автора поблагодарили: Proba (1). |
01.02.2010, 16:56 | #8 |
Участник
|
Цитата:
Сильные тормоза при разноске Заказа на продажу Как убрать знаки вопроса в мониторе запросов SQL? Аудит блокировок И для этого тоже нужно включить галочки в конфигурационой утилите, если у вас ax4.0 и выше. |
|
|
За это сообщение автора поблагодарили: andriy_s (1). |
01.02.2010, 17:12 | #9 |
Banned
|
Да, я тоже так делаю. В конце-концов, записи не только создаются, но и обновляются иногда.
|
|
|
За это сообщение автора поблагодарили: Kabardian (3). |
01.02.2010, 17:54 | #10 |
NavAx
|
|
|