25.06.2022, 00:22 | #1 |
Участник
|
Подсчет количества строк в Query (DAX2012)
Добрый день!
Обычно для подсчета количества строк всегда использовал queryRun::getQueryRowCount, однако появилась необходимость сделать тоже самое на темповой таблице, и тут возникла проблема. Как я не пытался написать, всегда в результате получаю 0. Есть какая то хитрость, или это невозможно? |
|
25.06.2022, 10:25 | #2 |
Участник
|
Каковы правильно заметили дело наверное во временных таблицах. Наверное стоит это учесть и доработать Академ найти корректный метод
|
|
25.06.2022, 12:13 | #3 |
Участник
|
Да, этот метод принимает Query и поэтому в случае временной таблицы не знает какую именно из временных таблиц (их курсоров) обрабатывать.
Есть методы, которые принимают QueryRun. А вот уже в QueryRun можно подсунуть конкретный курсор заполненной временной таблицы (методом setCursor). Это два метода класса SysQuery из AOT:
Они имеют особенности если запрос "многоэтажный". Если поищете по форуму эти методы, то будет понятно когда какой использовать (и использовать ли именно их). |
|
25.06.2022, 23:17 | #4 |
Участник
|
Их я тоже пробовал, и с setcursor, и с setrecord, и они тоже дают 0.
|
|
25.06.2022, 23:59 | #5 |
Участник
|
|
|
26.06.2022, 00:08 | #6 |
Участник
|
X++: queryRun = new QueryRun(query);
queryRun.setRecord(tmpTable);
i = SysQuery::countTotal(queryRun); |
|
26.06.2022, 08:03 | #7 |
Administrator
|
Всё правильно. Особенность временных таблиц состоит в том, чтобы не терять курсор. Т.е. если можно объявить переменную постоянной таблицы, чего-то в ней сделать, а затем объявить новую переменную и она уже увидит сделанные изменения, то в случае с временными таблицами такой подход не работает.
В случае с временными таблицами нужно ту переменную, которую наполнили данными - "таскать за собой" и пользоваться методами setTmpData() / linkToPhysicalInstance(), чтобы новую переменную привязывать к буферу той переменной, в которой лежат данные. Соответственно, в метод QueryRun::getQueryRowCount() действительно нельзя передать буфер временной таблицы, поэтому он работать для временных таблиц не будет Но и метод SysQuery::countTotal() внутри себя занимается перепаковкой Query и т.о. теряет исходный курсор. Поэтому, чтобы метод SysQuery::countTotal() работал корректно для временных таблиц - нужно сделать несколько изменений: 1. В метод countTotal нужно добавить параметр, через который будет передаваться буфер временной таблицы: X++: public client server static Integer countTotal(QueryRun _queryRun, Common _tmpBuffer = null)// VSUH, Корректный подсчет кол-ва записей во временной таблице, 06.04.2009 { container c = SysQuery::countPrim(_queryRun.pack(false), _tmpBuffer); return conpeek(c,1); } X++: private server static container countPrim(container _queryPack, Common _tmpBuffer = null) // VSUH, Корректный подсчет кол-ва записей во временной таблице, 06.04.2009 { Query countQuery; QueryRun countQueryRun; QueryBuildDataSource qbds; QueryBuildFieldList qbfl; Common common; Integer counter; Integer loops; ; countQueryRun = new QueryRun(_queryPack); // VSUH, Корректный подсчет кол-ва записей во временной таблице, 06.04.2009 --> if (_tmpBuffer) { countQueryRun.setCursor(_tmpBuffer); } // VSUH, Корректный подсчет кол-ва записей во временной таблице, 06.04.2009 <-- countQuery = countQueryRun.query(); qbds = countQuery.dataSourceNo(1); qbds.update(false); qbds.sortClear(); countQuery.clearGroupBy(); countQuery.clearOrderBy(); qbfl = qbds.fields(); qbfl.dynamic(false); qbfl.clearFieldList(); if (countQuery.dataSourceCount() == 1) qbds.addSelectionField(fieldNum(Common,RecId),SelectionField::Count); countQueryRun = new QueryRun(countQuery); // VSUH, Корректный подсчет кол-ва записей во временной таблице, 06.04.2009 --> if (_tmpBuffer) { countQueryRun.setCursor(_tmpBuffer); } // VSUH, Корректный подсчет кол-ва записей во временной таблице, 06.04.2009 <-- while (countQueryRun.next()) { common = countQueryRun.get(countQuery.dataSourceNo(1).table()); counter += common.RecId; loops++; } return [counter,loops]; }
__________________
Возможно сделать все. Вопрос времени Последний раз редактировалось sukhanchik; 26.06.2022 в 09:00. |
|
|
За это сообщение автора поблагодарили: Raven Melancholic (2), DesparioN (1). |
26.06.2022, 08:14 | #8 |
Участник
|
Не, всё нормально, это я ввел человека в заблуждение.
В стандарте действительно, не работает. У меня примерно тоже, что указал sukhanchik, правда уже внутри countPrim проверка посильнее: X++: if (_bufferTmp &&
_bufferTmp.isTmp() &&
countQuery.dataSourceCount() == 1)
{
countQueryRun.setCursor(_bufferTmp);
} X++: static void Job1(Args _args) { TmpABC tmpABC; QueryRun queryRun; Query query; QueryBuildDataSource qbds; Counter recordCount; ; tmpABC.clear(); tmpABC.initValue(); tmpABC.ItemId = 'ItemId1'; tmpABC.RefRecId = 1; tmpABC.insert(); tmpABC.ItemId = 'ItemId2'; tmpABC.RefRecId = 2; tmpABC.insert(); query = new Query(); qbds = query.addDataSource(tableNum(TmpABC)); queryRun = new QueryRun(query); recordCount = SysQuery::countTotal(queryRun, false, 0, tmpABC); info(strFmt("Всего записей %1.", recordCount)); } |
|
26.06.2022, 08:26 | #9 |
Участник
|
|
|
27.06.2022, 19:30 | #10 |
Участник
|
__________________
Felix nihil admirari |
|