|
07.11.2022, 23:28 | #1 |
Участник
|
Поиск источника SQL-запросов в коде X++ методом пересечения множеств перекрестных ссылок
Возможно, для кого-то это уже не новость, тем не менее. Опубликовал в блогах, как можно по тексту SQL-запроса найти его потенциальные источники в коде X++. Надеюсь, еще кому-нибудь пригодится при оптимизации производительности Аксапты.
|
|
|
За это сообщение автора поблагодарили: axm2017 (5), trud (5), sukhanchik (5), fed (5), Logger (5), PavelX (3), raz (5), Товарищ ♂uatr (4), dech (10). |
08.11.2022, 09:10 | #2 |
Участник
|
Цитата:
Сообщение от gl00mie
Здесь t100007_* - это экземпляр временной таблицы AccountingDistributionTmpJournalize
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
08.11.2022, 09:16 | #3 |
Участник
|
|
|
15.11.2022, 17:03 | #4 |
Участник
|
Я использую запрос для поиска пересечения элементов из запроса, т.е. в каком методе таблицы\поля из запроса одновременно используются:
X++: select distinct p2.Path from xRefPaths p join xRefReferences r on r.ReferencePathRecId = p.RecId join xRefPaths p2 on p2.RecId = r.xRefPathRecId join xRefNames n on n.RecId = r.xRefNameRecId where p.PATH = '\Data Dictionary\Tables\DIMENSIONATTRIBUTEVALUESETITEM' INTERSECT select distinct p2.Path from xRefPaths p join xRefReferences r on r.ReferencePathRecId = p.RecId join xRefPaths p2 on p2.RecId = r.xRefPathRecId join xRefNames n on n.RecId = r.xRefNameRecId where p.PATH = '\Data Dictionary\Tables\DIMENSIONATTRIBUTEVALUESETITEM\FIELDS\DIMENSIONATTRIBUTEVALUESET' INTERSECT <...> X++: SELECT T1.REFERENCEDISTRIBUTION, T4.EXCHANGERATE1, T4.EXCHANGERATE2, T4.REPORTINGEXCHANGERATE1, T4.REPORTINGEXCHANGERATE2 FROM tempdb."DBO".t100007_18B95DDA3C21488C85AC09C9FEB59FE5 T1 CROSS JOIN ACCOUNTINGDISTRIBUTION T2 CROSS JOIN SUBLEDGERJOURNALACCOUNTENTRYDISTRIBUTION T3 CROSS JOIN SUBLEDGERJOURNALACCOUNTENTRY T4 WHERE ((T1.PARTITION = @P1) AND (T1.REFERENCEDISTRIBUTION <> @P2)) AND ((T2.PARTITION = @P3) AND (T2.RECID = T1.REFERENCEDISTRIBUTION)) AND ((T3.PARTITION = @P4) AND (T3.ACCOUNTINGDISTRIBUTION = T1.REFERENCEDISTRIBUTION)) AND ((T4.PARTITION = @P5) AND (T4.RECID = T3.SUBLEDGERJOURNALACCOUNTENTRY)) GROUP BY T1.REFERENCEDISTRIBUTION, T4.EXCHANGERATE1, T4.EXCHANGERATE2, T4.REPORTINGEXCHANGERATE1, T4.REPORTINGEXCHANGERATE2 ORDER BY T1.REFERENCEDISTRIBUTION, T4.EXCHANGERATE1, T4.EXCHANGERATE2, T4.REPORTINGEXCHANGERATE1, T4.REPORTINGEXCHANGERATE2 X++: select distinct p2.Path from xRefPaths p join xRefReferences r on r.ReferencePathRecId = p.RecId join xRefPaths p2 on p2.RecId = r.xRefPathRecId join xRefNames n on n.RecId = r.xRefNameRecId where p.PATH = '\Data Dictionary\Tables\ACCOUNTINGDISTRIBUTION' INTERSECT select distinct p2.Path from xRefPaths p join xRefReferences r on r.ReferencePathRecId = p.RecId join xRefPaths p2 on p2.RecId = r.xRefPathRecId join xRefNames n on n.RecId = r.xRefNameRecId where p.PATH = '\Data Dictionary\Tables\SUBLEDGERJOURNALACCOUNTENTRYDISTRIBUTION' INTERSECT select distinct p2.Path from xRefPaths p join xRefReferences r on r.ReferencePathRecId = p.RecId join xRefPaths p2 on p2.RecId = r.xRefPathRecId join xRefNames n on n.RecId = r.xRefNameRecId where p.PATH = '\Data Dictionary\Tables\SUBLEDGERJOURNALACCOUNTENTRY' INTERSECT select distinct p2.Path from xRefPaths p join xRefReferences r on r.ReferencePathRecId = p.RecId join xRefPaths p2 on p2.RecId = r.xRefPathRecId join xRefNames n on n.RecId = r.xRefNameRecId where p.PATH = '\Data Dictionary\Tables\AccountingDistributionTmpJournalize' \Classes\SubledgerJournalizer\loadaccountingDistributionTmp \Classes\SubledgerJournalizer\loadReferenceDistributionInformation \Classes\SubledgerJournalizer\PSALoadaccountingDistReleaseTmp Предварительно превращаем tableid временной таблицы в имя джобом: X++: info(strFmt("%1", tableId2name(100007))); |
|
|
За это сообщение автора поблагодарили: Raven Melancholic (10), Владимир Максимов (10), raz (5), gl00mie (10), macklakov (18). |
02.09.2024, 11:05 | #5 |
Участник
|
Делаю в акс2012 тоже самое джобом. Результат смотрю в стандартной форме ссылок без группировки.
Ранже делаю разный для случая если хочется посмотреть пересечения с системными полями RecId и пр.. Для них нет объекта в xRefPaths. X++: SysDictField df; TreeNode node; Map map = new Map(Types::Integer, Types::Class); TmpRecIdFilter tmp; Args args = new Args(); FormRun fr; FormDataSource fds; QueryBuildDataSource ds; Counter cnt; QueryRun qr = new QueryRun(new Query()); ; map.insert(1, new SysDictField(tableNum(AccountingDistributionTmpJournalize), FieldNum(AccountingDistributionTmpJournalize, ReferenceDistribution))); map.insert(2, new SysDictField(tableNum(SubledgerJournalAccountEntryDistribution), FieldNum(SubledgerJournalAccountEntryDistribution, SubledgerJournalAccountEntry))); //map.insert(3, new SysDictField(tableNum(SubledgerJournalAccountEntryDistribution), FieldNum(SubledgerJournalAccountEntryDistribution, AccountingDistribution))); //map.insert(4, new SysDictField(tableNum(SubledgerJournalAccountEntry), FieldNum(SubledgerJournalAccountEntry, ExchangeRate1))); //map.insert(5, new SysDictField(tableNum(SubledgerJournalAccountEntry), FieldNum(SubledgerJournalAccountEntry, REPORTINGEXCHANGERATE1))); // ... for(cnt = 1; cnt<=map.elements(); cnt++) { df = map.lookup(cnt); node = TreeNode::findNode(df.path()); if (ds) { ds = SysQuery::addExistsJoin(ds, tableNum(xRefReferences), false); ds.addLink(fieldNum(xRefReferences, xRefPathRecId), fieldNum(xRefReferences, xRefPathRecId)); } else ds = qr.query().addDataSource(tableNum(xRefReferences)); if (node) ds.addRange(fieldNum(xRefReferences, referencePathRecId)).value(queryValue(xRefPaths::find(node.treeNodePath()).RecId)); else ds.addRange(fieldNum(xRefReferences, xRefNameRecId)).value(queryValue(xRefNames::find(xRefKind::TableField, df.tableName(), df.name(), false, "").RecId)); } cnt = 0; while (qr.next()) { cnt++; tmp.RefRecId = qr.getNo(1).RecId; tmp.insert(); } //Просмотрим операции в форме args = new Args(); args.name(formstr(xRefReferencesUsedByTypedTree)); fr = classfactory.formRunClass(args); fr.init(); fds = fr.dataSource(1); ds = fds.queryBuildDataSource(); ds = SysQuery::addExistsJoin(ds, tableNum(TmpRecIdFilter), false); ds.addLink(fieldNum(xRefReferences, RecId), fieldNum(TmpRecIdFilter, RefRecId)); fr.run(); fds.queryRun().setCursor(tmp); fds.research(); fr.detach(); info(strFmt("cnt - %1", cnt)); Последний раз редактировалось Perc; 02.09.2024 в 11:08. |
|
|
За это сообщение автора поблагодарили: dech (10). |