|
![]() |
#1 |
Участник
|
Ларчик у меня открылся вот как. Изначально почитав http://www.axaptapedia.com/Expressions_in_query_ranges я использовал ExistsJoin. Потом спасибо S.Kuskov тип связи изменился на InnerJoin. И тогда встал вопрос, а почему структура query до сих пор такая? Почему бы не поднять InventLocation выше? Поднял и все заработало. Код который бил показан он тестовый и поэтому упрошенный. Сейчас рабочий код выглядит так
X++: qbds = query.addDataSource(tablenum(InventTransferTable)); qbds.orderMode(OrderMode::GroupBy); qbds.addSortField(fieldnum(InventTransferTable, TransferId)); qbds.addSortField(fieldnum(InventTransferTable, InventLocationIdTo)); qbds.addSortField(fieldnum(InventTransferTable, InventLocationIdFrom)); qbds.addSortField(fieldnum(InventTransferTable, InventLocationIdTransit)); qbds.addSortField(fieldnum(InventTransferTable, InventLocationIdLater)); qbds.addSortField(fieldnum(InventTransferTable, ReceiveDate)); qbds.addSortField(fieldnum(InventTransferTable, TransferStatus)); qbds.addSortField(fieldnum(InventTransferTable, InventLocationIdLater)); if (fromDate && toDate)//Дата { qbds.addRange(fieldnum(InventTransferTable, ReceiveDate)).value(strfmt('%1..%2', fromDate, toDate)); } if (receivedOnly) { qbds.addRange(fieldnum(InventTransferTable, TransferStatus)).value(QueryValue(InventTransferStatus::Received)); } else { qbds.addRange(fieldnum(InventTransferTable, TransferStatus)).value(QueryValue(InventTransferStatus::Shipped)); qbds.addRange(fieldnum(InventTransferTable, TransferStatus)).value(QueryValue(InventTransferStatus::Received)); } if (inventLocationId_From)//Отправлено Откуда { qbds.addRange(fieldnum(InventTransferTable, InventLocationIdFrom)).value(inventLocationId_From); } if (inventLocationId_To)//Отправлено Куда { qbds.addRange(fieldnum(InventTransferTable, InventLocationIdTo)).value(inventLocationId_To); } if (inventLocationType != InventLocationType::Standard) { qbdsInventLocationFrom = qbds.addDataSource(tablenum(InventLocation)); qbdsInventLocationFrom.addLink(fieldNum(InventTransferTable, InventLocationIdFrom), fieldNum(InventLocation, InventLocationId)); qbdsInventLocationFrom.joinMode(JoinMode::InnerJoin); qbdsInventLocationFrom.fetchMode(QueryFetchMode::One2One); qbdsInventLocationTo = qbds.addDataSource(tableNum(InventLocation)); qbdsInventLocationTo.addLink(fieldNum(InventTransferTable, InventLocationIdTo), fieldNum(InventLocation, InventLocationId)); qbdsInventLocationTo.joinMode(JoinMode::InnerJoin); qbdsInventLocationTo.fetchMode(QueryFetchMode::One2One); qbrDataAreaId = qbdsInventLocationTo.addRange(fieldNum(InventLocation, DataAreaId)); qbrDataAreaId.value(strFmt('((%1.%3 == %4) || (%2.%3 == %4))', qbdsInventLocationFrom.name(), qbdsInventLocationTo.name(), fieldStr(InventLocation, InventLocationType), any2int(inventLocationType))); } qbds1 = qbds.addDataSource(tablenum(InventTransferLine)); qbds1.addLink(fieldnum(InventTransferTable, TransferId), fieldnum(InventTransferLine , TransferId)); qbds1.joinMode(JoinMode::InnerJoin); qbds1.orderMode(OrderMode::GROUPBY); qbds1.fetchMode(QueryFetchMode::One2One); qbds1.addSortField(fieldnum(InventTransferLine, ItemId)); qbds1.addSortField(fieldnum(InventTransferLine, Out_ItemId)); qbds1.addSortField(fieldnum(InventTransferLine, QtyTransfer)); qbds2 = qbds1.addDataSource(tableNum(InventSum)); qbds2.addLink(fieldnum(InventTransferLine, ItemId), fieldNum(InventSum, ItemId)); qbds2.joinMode(joinMode::InnerJoin); qbds2.orderMode(OrderMode::GROUPBY); qbds2.fetchMode(QueryFetchMode::One2One); qbds2.addSortField(fieldnum(InventSum, ItemId)); qbds2.addSelectionField(fieldnum(InventSum, ReservPhysical), SelectionField::SUM); qbds2.addSelectionField(fieldnum(InventSum, PostedQty), SelectionField::SUM); qbds2.addSelectionField(fieldnum(InventSum, Received), SelectionField::SUM); qbds2.addSelectionField(fieldnum(InventSum, Deducted), SelectionField::SUM); qbds2.addSelectionField(fieldnum(InventSum, Registered), SelectionField::SUM); qbds2.addSelectionField(fieldnum(InventSum, Picked), SelectionField::SUM); qbds2.addRange(fieldnum(InventSum, Closed)).value(SysQuery::value(NoYes::No)); qbds2.addRange(fieldNum(InventSum, PhysicalInvent)).value("> 0"); queryRun = new QueryRun(query); |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
![]() |
#2 |
Участник
|
это понятно и нормально.
про код тоже понятно. но проблема то не решена. в скобках у вас по прежнему названия датасорсов, а в самом тексте запроса используются названия таблиц. аксапта не проверяет синтаксис внутри скобок. поэтому и не выдает ошибки. но с точки зрения SQL запрос будет синтаксически неверным. Цитата:
Сообщение от smailik
![]() X++: qbrDataAreaId = qbdsInventLocationTo.addRange(fieldNum(InventLocation, DataAreaId)); qbrDataAreaId.value(strFmt('((%1.%3 == %4) || (%2.%3 == %4))', qbdsInventLocationFrom.name(), qbdsInventLocationTo.name(), fieldStr(InventLocation, InventLocationType), any2int(inventLocationType))); } |
|
![]() |
#3 |
Участник
|
поговорите с администратором. )
но лучше начните использовать АОТ для 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. |
|
![]() |
#4 |
Участник
|
__________________
Мои утилиты для Аксапты версий 3.0-2012: http://aceofdatabase.blogspot.com/ |
|
![]() |
#5 |
Участник
|
При генерации SQL, насколько я знаю, query использует имена источников данных, а не таблиц. просто если их явно не указывать, они генерируются автоматически
|
|
|
За это сообщение автора поблагодарили: mazzy (2). |
![]() |
#6 |
Участник
|
Сейчас при изменении InventLocationType результат меняется. Сделал визуальную проверку выводимым данных. Фильтр накладывается верно.
|
|
|
За это сообщение автора поблагодарили: mazzy (2). |
![]() |
#7 |
Участник
|
Да. Тогда отлично. Тогда в акс4 работает правильно, просто в toString() отображаются неполная информация.
|
|
![]() |
#8 |
Участник
|
Огромное спасибо. Не могу поставить благодарность под сообщением, так как сделал это уже под другим. Надо наверное пообщаться с администратором на эту тему
![]() |
|
![]() |
#9 |
Участник
|
|
|
|
За это сообщение автора поблагодарили: mazzy (2). |
![]() |
#10 |
Участник
|
Цитата:
Сообщение от 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) |
|
![]() |
#11 |
Участник
|
Всем доброго дня. Столкнулся с подобной задачей, но теперь мне надо наложить условие И на одно и тоже поле таблицы. А именно примерно следующее:
X++: qbr.value(strfmt('((%1 >= %2) && (%1 == %3))', fieldStr(myTable, TransDate), tableParameters.DateFrom, transDateFilter)); На данный момент получаю ошибку "Ошибка расширенного диапазона запроса: Ожидается правая круглая скобка рядом с 23." Если перед strfmt добавить SysQuery::value, то ошибки нет, но и данных нет. Прошу совета как реализовать необходимую задачу. |
|
![]() |
#12 |
Участник
|
Причина ошибки - неверное строковое представление даты. В следующий раз используйте date2StrXpp(), как в примере у dim-gin.
__________________
// no comments |
|
|
За это сообщение автора поблагодарили: smailik (2). |
![]() |
#13 |
Участник
|
равенство одним символом =, а не двумя
http://axapta.mazzy.ru/lib/search/ |
|
![]() |
#14 |
Участник
|
На ошибку это не повлияло.
Когда заработает надо поизучать этот вопрос http://www.axaptapedia.com/Expressions_in_query_ranges тут "==" Последний раз редактировалось smailik; 06.09.2017 в 19:55. |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
![]() |
#15 |
Участник
|
По это же ссылке приведен пример работы с датой в Query:
X++: queryBuildRange.value(strFmt('(ModifiedDate > %1)', Date2StrXpp(01\01\2000))); |
|
![]() |
#16 |
Участник
|
Проблема не с обычным фильтром, а с условием И по одному и тому же полю
|
|
![]() |
#17 |
Участник
|
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). |
![]() |
#18 |
Участник
|
Огромное спасибо. Заработался. За сегодняшнюю дату то у меня записей нет. Система правильно делала что показывала пустоту.
|
|