AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 07.11.2022, 23:28   #1  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
! Поиск источника 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  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,692 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от gl00mie
Здесь t100007_* - это экземпляр временной таблицы AccountingDistributionTmpJournalize
А это как определить? Или тут это было просто для примера?
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 08.11.2022, 09:16   #3  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
А это как определить? Или тут это было просто для примера?
Для определения AOT-имени TempDB-таблиц из SQL-запросов в AX2012 я обычно запускаю job вида:
X++:
info(tableid2name(100007));
Старый 15.11.2022, 17:03   #4  
DarkSpirit22 is offline
DarkSpirit22
Участник
Аватар для DarkSpirit22
 
13 / 94 (4) ++++
Регистрация: 07.11.2013
Адрес: СПб
Я использую запрос для поиска пересечения элементов из запроса, т.е. в каком методе таблицы\поля из запроса одновременно используются:
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)));
Можно докинуть еще блоки INTERSECT + select для уменьшения кол-ва выходных данных.
За это сообщение автора поблагодарили: Raven Melancholic (10), Владимир Максимов (10), raz (5), gl00mie (10), macklakov (18).
Старый 02.09.2024, 11:05   #5  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Делаю в акс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).
Теги
xref

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
DAX2012R3 перенос перекрестных ссылок Wamr DAX: Администрирование 1 22.09.2014 15:28
ax2009: кто юзал Startup command: CompileAll_+ для периодического обновления перекрестных ссылок? mazzy DAX: Администрирование 11 25.08.2010 08:50
Обновление перекрестных ссылок ест память Sada DAX: Программирование 22 11.10.2006 18:22
Мониторинг запросов SQL exceptor DAX: Программирование 11 21.02.2006 09:16
Просмотр SQL запросов к БД с помощью файла Log Anton Sk. DAX: База знаний и проекты 3 25.01.2002 16:31

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 21:23.