19.06.2017, 21:26 | #41 |
Участник
|
Да. Тогда отлично. Тогда в акс4 работает правильно, просто в toString() отображаются неполная информация.
|
|
19.06.2017, 21:36 | #42 |
Участник
|
Огромное спасибо. Не могу поставить благодарность под сообщением, так как сделал это уже под другим. Надо наверное пообщаться с администратором на эту тему
|
|
19.06.2017, 22:00 | #43 |
Участник
|
поговорите с администратором. )
но лучше начните использовать АОТ для query вместо простыней кода. и всегда экранируйте значение перед тем как записать range.value. вот так категорически неправильно: X++: value(inventLocationId_From) X++: value(SysQuery::value(inventLocationId_From)) или любые друге спец.символы. http://axapta.mazzy.ru/lib/search/ ========================= Цитата:
в общем старая добрая проблема с множественным Exist Join в нескольких подчиненных таблицах воспроизводится и в самых распоследних билдах акс2012. Если есть несколько подчиненных таблиц с Exist Join и InnerJoin, то возникает ошибка при создании SQL-запроса. Независимо от положения подчиненных таблиц, от group by и прочих факторов. ========================= Господи, хорошо то как в старой версии! И все-таки лучшей версией была акс2009. Последний раз редактировалось mazzy; 19.06.2017 в 22:18. |
|
19.06.2017, 22:00 | #44 |
Участник
|
|
|
|
За это сообщение автора поблагодарили: mazzy (2). |
19.06.2017, 22:08 | #45 |
Участник
|
Цитата:
Сообщение от mazzy
аксапта не гарантирует, что query будет выполнен одним SQL-запросом.
очень часто аксапта разбивает выполнение Query на несколько SQL-запросов. разбитие зависит от временных таблиц, кэшируемых таблиц, сложных запросов с невложенными связями, existJoin. https://msdn.microsoft.com/en-us/library/bb314836.aspx вполне вероятно, что аксапта разбила запрос на несколько. И вроде было связано с версией SQL - что-то там происходило, когда в запросе участвуют много таблиц. Типа планы оптимизации не рассчитывались... или что-то вроде того. Кстати, алиасы таблиц раньше по-другому генерились. Помню, что были первые буквы латинского алфавита A,B,C... А теперь Т1, Т2, Т3... Цитата:
Сообщение от db
SELECT A.ITEMGROUPID,A.ITEMID,A.ITEMNAME,A.ITEMTYPE,A.PURCHMODEL,A.HEIGHT,A.WIDTH,A.SALESMODEL,
A.COSTGROUPID,A.REQGROUPID,A.PRIMARYVENDORID,A.NETWEIGHT,A.DEPTH,A.UNITVOLUME,A.BOMUNITID,A.DENSITY, A.DEL_SCRAPTYPEID,A.DIMENSION,A.DIMENSION2_,A.DIMENSION3_,A.DIMENSION4_,A.DIMENSION5_,A.COSTMODEL, A.USEALTITEMID,A.ALTITEMID,A.INTRACODE,A.BOMMANUALCONSUMP,A.BOMMANUALRECEIPT, A.STOPEXPLODE,A.DEL_COVPERINVENTLOCATION,A.PHANTOM,A.INTRAUNIT,A.BOMLEVEL,A.BATCHNUMGROUPID, A.AUTOREPORTFINISHED,A.ORIGCOUNTRYID,A.STATISTICSFACTOR,A.ALTCONFIGID,A.STANDARDCONFIGID, A.DEL_CONFIGACTIVE,A.PRODPOOLID,A.PROPERTYID,A.ABCTIEUP,A.ABCREVENUE,A.ABCVALUE,A.ABCCONTRIBUTIONMARGIN, A.COMMISSIONGROUPID,A.DEL_BARCODE,A.DEL_BARCODETYPE,A.CONFIGURABLE,A.SALESPERCENTMARKUP, A.SALESCONTRIBUTIONRATIO,A.SALESPRICEMODELBASIC,A.MINAVERAGESETTLE,A.NAMEALIAS,A.PRODGROUPID, A.PROJCATEGORYID,A.GROSSDEPTH,A.GROSSWIDTH,A.GROSSHEIGHT,A.STANDARDPALLETQUANTITY,A.QTYPERLAYER, A.SORTCODE,A.CONFIGSIMILAR,A.SERIALNUMGROUPID,A.DIMGROUPID,A.MODELGROUPID,A.ITEMBUYERGROUPID, A.TAXPACKAGINGQTY,A.DEL_TEMPLATE,A.WMSPALLETTYPEID,A.ORIGSTATEID,A.STOPEXPLODEPRICE,A.WMSPICKINGQTYTIME, A.TARAWEIGHT,A.PACKAGINGGROUPID,A.SCRAPVAR,A.SCRAPCONST,A.ITEMDIMCOMBINATIONAUTOCREATE, A.ITEMDIMCOSTPRICE,A.ITEMIDCOMPANY,A.PBAITEMCONFIGURABLE,A.PBAINVENTITEMGROUPID, A.GROSSWEIGHT_RU,A.PACKING_RU,A.ASSETGROUPID_RU,A.ASSETID_RU,A.RECID, B.ITEMID,B.MODULETYPE,B.UNITID,B.PRICE,B.PRICEUNIT,B.MARKUP,B.LINEDISC,B.MULTILINEDISC,B.ENDDISC, B.QUANTITY,B.LOWESTQTY,B.HIGHESTQTY,B.TAXITEMGROUPID,B.BLOCKED,B.DELIVERYTIME,B.INVENTLOCATIONID, B.MANDATORYINVENTLOCATION,B.STANDARDQTY,B.MARKUPGROUPID,B.PRICEDATE,B.PRICEQTY,B.ALLOCATEMARKUP, B.OVERDELIVERYPCT,B.UNDERDELIVERYPCT,B.SUPPITEMGROUPID,B.CALENDARDAYS,B.INTERCOMPANYBLOCKED, B.PRICESECCUR_RU,B.MARKUPSECCUR_RU,B.RECID,C.UNITID,C.TXT,C.UNITDECIMALS,C.UNITSYSTEM,C.CODEOKEI_RU,C.RECID FROM INVENTTABLE A(NOLOCK) ,INVENTTABLEMODULE B(NOLOCK) ,UNIT C(NOLOCK) WHERE (A.DATAAREAID=?) AND ((B.DATAAREAID=?) AND ((B.MODULETYPE=?) AND (A.ITEMID=B.ITEMID))) AND ((C.DATAAREAID=?) AND (B.UNITID=C.UNITID)) ORDER BY A.DATAAREAID,A.ITEMID OPTION(FAST 9) |
|
19.06.2017, 22:24 | #46 |
Участник
|
Если брать исходный текст с Query, то можно попробовать указать fetch mode 1:1 явно у всех DS (кроме первого, разумеется).
Если я правильно понял задачу, требуется что-то типа такого: X++: Query q; QueryBuildDataSource qbdsIJT, qbdsIJTr, qbdsIL, qbdsIT; QueryBuildRange qbr; QueryRun qr; ; q = new Query(); // смысл group by мне непонятен qbdsIJT = q.addDataSource(tablenum(InventJournalTable)); // qbdsIJT.orderMode(OrderMode::GroupBy); qbdsIJT.addSelectionField(fieldNum(InventJournalTable, JournalId), SelectionField::Database); qbdsIJT.addSelectionField(fieldNum(InventJournalTable, InventLocationId), SelectionField::Database); qbdsIJT.addSelectionField(fieldNum(InventJournalTable, InventLocationIdTo), SelectionField::Database); qbdsIJT.addRange(fieldnum(InventJournalTable, JournalNameId)).value('ПРС'); qbdsIJTr = qbdsIJT.addDataSource(tablenum(InventJournalTrans)); qbdsIJTr.addSelectionField(fieldNum(InventJournalTrans, InventTransId), SelectionField::Database); qbdsIJTr.addSelectionField(fieldNum(InventJournalTrans, ItemId), SelectionField::Database); qbdsIJTr.addSelectionField(fieldNum(InventJournalTrans, InventDimId), SelectionField::Database); qbdsIJTr.addSelectionField(fieldNum(InventJournalTrans, Qty), SelectionField::Database); qbdsIJTr.relations(true); qbdsIJTr.joinMode(JoinMode::InnerJoin); // qbdsIJTr.orderMode(OrderMode::GROUPBY); qbdsIJTr.fetchMode(QueryFetchMode::One2One); qbdsIT = qbdsIJTr.addDataSource(tableNum(InventTable)); qbdsIT.relations(true); qbdsIT.addSelectionField(fieldNum(InventTable, ItemName), SelectionField::Database); qbdsIT.addSelectionField(fieldNum(InventTable, ItemGroupId), SelectionField::Database); qbdsIT.joinMode(joinMode::InnerJoin); // qbdsItl.orderMode(OrderMode::GROUPBY); qbdsIT.fetchMode(QueryFetchMode::One2One); // можно объединить 2 DS в одну конструкцию qbdsIT = qbdsIJT.addDataSource(tableNum(InventLocation)); qbdsIT.fetchMode(QueryFetchMode::One2One); qbdsIT.joinMode(JoinMode::ExistsJoin); qbdsIT.relations(false); // это на самом деле relation qbr = qbdsIT.addRange(fieldNum(InventLocation, InventLocationId)); qbr.value(strFmt('(%1.%2 = %4.%5) || (%1.%3 = %4.%5)', qbdsIJT.name(), fieldStr(InventJournalTable, InventLocationId), fieldStr(InventJournalTable, InventLocationIdTo), qbdsIT.name(), fieldStr(InventLocation, InventLocationId)) ); // прочие условия (на справочник складов) //qbdsIT.addRange(fieldNum(... // проверка, что не потерялся какой-нибудь DS qr = new QueryRun(q); if (qr.next()) info(strFmt('%1 %2 %3', qr.get(tableNum(InventJournalTable)).(fieldNum(InventJournalTable, JournalId)), qr.get(tableNum(InventJournalTrans)).(fieldNum(InventJournalTrans, InventTransId)), qr.get(tableNum(InventTable)).(fieldNum(InventTable, ItemName)) )); info('DAX query: '+qbdsIJT.toString()); info(strFmt('Query qty: %1', SysQuery::qrCount(new QueryRun(q)))); P.S. В стандарте, конечно же, нет полей со складами в шапке скл.журналов, добавлены вручную. Пока строчил, уже всё порешали))) Последний раз редактировалось dim-gin; 19.06.2017 в 22:28. Причина: опоздал с сообщением |
|
|
За это сообщение автора поблагодарили: mazzy (2), smailik (1), alex55 (1). |
19.06.2017, 22:32 | #47 |
Участник
|
group by там похоже, потому что они что-то считают (судя по промелькнувшему SysQuery::count)
похоже просто код не полный. да, проблема как раз в нескольких existsJoin в подчиненных таблицах. с одним existsJoin никаких проблем Цитата:
Сообщение от dim-gin
X++: // можно объединить 2 DS в одну конструкцию qbdsIT = qbdsIJT.addDataSource(tableNum(InventLocation)); qbdsIT.fetchMode(QueryFetchMode::One2One); qbdsIT.joinMode(JoinMode::ExistsJoin); qbdsIT.relations(false); // это на самом деле relation qbr = qbdsIT.addRange(fieldNum(InventLocation, InventLocationId)); qbr.value(strFmt('(%1.%2 = %4.%5) || (%1.%3 = %4.%5)', qbdsIJT.name(), fieldStr(InventJournalTable, InventLocationId), fieldStr(InventJournalTable, InventLocationIdTo), qbdsIT.name(), fieldStr(InventLocation, InventLocationId)) ); // прочие условия (на справочник складов) опять же скорее всего, нам не все условия показали, а только самое тривиальное. и если условия в ТЗ будут углублены и расширены (а они будут углублены) то такой маневр будет оооочень сильно мешать. |
|
19.06.2017, 22:44 | #48 |
Участник
|
2 mazzy:
Да, это не самое элегантное решение. Но разве исходные 2 exists join'а с OR намного проще в выполнении для БД? Или Вы подразумеваете другой смысл под словом "мешать"? Последний раз редактировалось dim-gin; 19.06.2017 в 22:45. Причина: опечатка |
|
19.06.2017, 23:00 | #49 |
Участник
|
для БД не проще.
мешать будет человеку. если сейчас условие упаковать в один existJoin, то с появлением новых условий на склады, условие придется делать все более навороченным и сильно непонятным и для программиста, и для пользователя. пользователь появляется поскольку часто готовый query может оказаться в стандартном диалоге, где пользователь может его подправить. даже опытный пользователь повесится. придется делать этот range::Locked. а затем придумывать обходные пути чтобы таки как-то разрешить. да, из кода видно, что в данном случае разработчики не парятся с критериями, а используют диалог с единственным значением для фильтра в каждом range. и хорошо, если это значение можно подставить из выпадающего списка ))) но рано или поздно они могут захотеть таки перейти на полноценные критерии вместо единственного значения. этот workaround сделает любое расширение условия по складам очень нетривиальным и сложным. |
|
|
За это сообщение автора поблагодарили: dim-gin (1). |
06.09.2017, 19:37 | #50 |
Участник
|
Всем доброго дня. Столкнулся с подобной задачей, но теперь мне надо наложить условие И на одно и тоже поле таблицы. А именно примерно следующее:
X++: qbr.value(strfmt('((%1 >= %2) && (%1 == %3))', fieldStr(myTable, TransDate), tableParameters.DateFrom, transDateFilter)); На данный момент получаю ошибку "Ошибка расширенного диапазона запроса: Ожидается правая круглая скобка рядом с 23." Если перед strfmt добавить SysQuery::value, то ошибки нет, но и данных нет. Прошу совета как реализовать необходимую задачу. |
|
06.09.2017, 19:49 | #51 |
Участник
|
равенство одним символом =, а не двумя
http://axapta.mazzy.ru/lib/search/ |
|
06.09.2017, 19:52 | #52 |
Участник
|
На ошибку это не повлияло.
Когда заработает надо поизучать этот вопрос http://www.axaptapedia.com/Expressions_in_query_ranges тут "==" Последний раз редактировалось smailik; 06.09.2017 в 19:55. |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
06.09.2017, 20:54 | #53 |
Участник
|
По это же ссылке приведен пример работы с датой в Query:
X++: queryBuildRange.value(strFmt('(ModifiedDate > %1)', Date2StrXpp(01\01\2000))); |
|
06.09.2017, 21:02 | #54 |
Участник
|
Проблема не с обычным фильтром, а с условием И по одному и тому же полю
|
|
06.09.2017, 22:25 | #55 |
Участник
|
1. А почему нельзя одно из условий отбросить в самом приложении (а не перекладывать эту функцию на БД)?
2. Даже если и нельзя, то, объединив уже предложенные советы, получаем перевариваемый вариант (2009, трёшка): X++: Query q; QueryBuildDataSource qbds; QueryRun qr; EmplTable empl; str sRange; int iCnt; ; q = new Query(); qbds = q.addDataSource(tableNum(EmplTable)); sRange = strFmt('(%1.%2 >= %3) && (%1.%2 = %4)', qbds.name(), fieldStr(EmplTable, PayEmploymentDate_RU), date2StrXpp(01\09\2017), date2StrXpp(today())); //info(sRange); qbds.addRange(fieldNum(EmplTable, PayEmploymentDate_RU)).value(sRange); //info(qbds.toString()); qr = new QueryRun(q); while (qr.next()) iCnt++; info(int2str(iCnt)); |
|
|
За это сообщение автора поблагодарили: smailik (2), dech (2). |
06.09.2017, 23:20 | #56 |
Участник
|
Огромное спасибо. Заработался. За сегодняшнюю дату то у меня записей нет. Система правильно делала что показывала пустоту.
|
|
07.09.2017, 09:14 | #57 |
Участник
|
Причина ошибки - неверное строковое представление даты. В следующий раз используйте date2StrXpp(), как в примере у dim-gin.
__________________
// no comments |
|
|
За это сообщение автора поблагодарили: smailik (2). |
07.09.2017, 11:28 | #58 |
Участник
|
__________________
Мои утилиты для Аксапты версий 3.0-2012: http://aceofdatabase.blogspot.com/ |
|