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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 10.11.2008, 11:27   #1  
miklenew is offline
miklenew
Участник
Аватар для miklenew
MCBMSS
1C
Лучший по профессии 2009
 
1,688 / 433 (18) +++++++
Регистрация: 10.07.2006
Адрес: г. Ликино-Дулёво
Вопрос по force*
Есть класс InventSumOpenTransact\setValueQty()
В нём код
X++:
        while select forcePlaceholders forceSelectOrder forceNestedLoop inventTrans
            index hint OpenItemIdx
            where inventTrans.itemId            == itemId                       &&
                  inventTrans.valueOpen         == InventTransOpen::Yes         &&
                  inventTrans.statusReceipt     >= StatusReceipt::None          &&
                  inventTrans.statusReceipt     <= StatusReceipt::Purchased     &&
                  inventTrans.statusIssue       >= StatusIssue::None            &&
                  inventTrans.statusIssue       <= StatusIssue::Sold            &&
                  inventTrans.dateFinancial     <= perDate
        #inventDimJoin(inventTrans.inventDimId,inventDim,inventDimCriteria,inventDimParm,dimIdIdx)
        {
            this.add(inventTrans);
        }
Он выдаёт мне не правильное значение inventTrans.CostAmountPosted
Если делаю убираю force*, правильное значение
X++:
        while select inventTrans
            index hint OpenItemIdx
            where inventTrans.itemId            == itemId                       &&
                  inventTrans.valueOpen         == InventTransOpen::Yes         &&
                  inventTrans.statusReceipt     >= StatusReceipt::None          &&
                  inventTrans.statusReceipt     <= StatusReceipt::Purchased     &&
                  inventTrans.statusIssue       >= StatusIssue::None            &&
                  inventTrans.statusIssue       <= StatusIssue::Sold            &&
                  inventTrans.dateFinancial     <= perDate
        #inventDimJoin(inventTrans.inventDimId,inventDim,inventDimCriteria,inventDimParm,dimIdIdx)
        {
            this.add(inventTrans);
        }
Если делаю так, тоже правильно
X++:
        inventTrans.disableCache(true);
        while select forcePlaceholders forceSelectOrder forceNestedLoop inventTrans
            index hint OpenItemIdx
            where inventTrans.itemId            == itemId                       &&
                  inventTrans.valueOpen         == InventTransOpen::Yes         &&
                  inventTrans.statusReceipt     >= StatusReceipt::None          &&
                  inventTrans.statusReceipt     <= StatusReceipt::Purchased     &&
                  inventTrans.statusIssue       >= StatusIssue::None            &&
                  inventTrans.statusIssue       <= StatusIssue::Sold            &&
                  inventTrans.dateFinancial     <= perDate
        #inventDimJoin(inventTrans.inventDimId,inventDim,inventDimCriteria,inventDimParm,dimIdIdx)
        {
            this.add(inventTrans);
        }
Один раз уже с этим сталкивался.
Только тогда не обратил внимание что это из-за force*
Код был мой и за результаты был уверен спокойно поставил inventTrans.disableCache(true) и всё ок.
Может кто-то обяснит почему с использованием force* могут данные не актуальные вернуться. Может на Oracle какие-нибудь дополнительные настройки поставить, чтоб правильно запрос отрабатывал.
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему.
Старый 10.11.2008, 11:47   #2  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
По идее - force не должен влиять. Это же только подсказка оптимизатору, как лучше выполнить запрос. Результат отличаться не должен.

Возможно причина в том что Аксапта в случае с force - кеширует запрос. А когда вы ставите без force - то она видит что запрос отличается от того который был ранее и кеш не использует.

В общем правильнее принудительно отключить кеширование
X++:
inventTrans.disableCache(true);
Кстати, если не лень - попробуйте в случае с force подсмотреть какие запросы уходят к БД - подозреваю что никаких.

Последний раз редактировалось Logger; 10.11.2008 в 11:51.
Старый 10.11.2008, 11:51   #3  
miklenew is offline
miklenew
Участник
Аватар для miklenew
MCBMSS
1C
Лучший по профессии 2009
 
1,688 / 433 (18) +++++++
Регистрация: 10.07.2006
Адрес: г. Ликино-Дулёво
Если бы у InventTrans не было бы recId (группировка какая нибудь была), я бы тоже подумал, что может запрос не правильный ушёл.
Но ведь recId есть. Я даже find по нему пробовал перед запросом делать.
find возвращает правильное значение, а запрос нет.
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему.
Старый 10.11.2008, 11:55   #4  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Похожий глюк
Глюки RecordViewCache
Старый 10.11.2008, 11:56   #5  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Вы сперва профайлером посмотрите- запрос на БД какой-нить уходит вообще или нет.
В случае когда глючит кеширование - запрос на БД вообще не уходит.
Старый 10.11.2008, 13:33   #6  
glibs is offline
glibs
Member
Сотрудники компании It Box
Most Valuable Professional
Лучший по профессии 2011
Лучший по профессии 2009
 
4,942 / 911 (40) +++++++
Регистрация: 10.06.2002
Адрес: I am from Kyiv, Ukraine. Now I am in Moscow. For private contacts: glibs@hotmail.com
Наблюдал похожий глюк именно на Oracle (на MS SQL не удалось тогда воспроизвести).

Запрос был простенький типа

select currency
where currency.CurrencyCode == "XXXY"

Когда в качестве кода валюты передавался код несуществующей валюты длиной в 4 символа (тестировалась проверка на некорректное значение валюты при импорте из другой системы), то возвращалась запись, код которой совпадал с первыми тремя символами неправильного кода. Ожидалось же, что запись не вернется и система выругается. Дальше из-за этого получался какой-то конфуз. Т.е. в режиме FORCEPLACEHOLDERS Oracle как-то умудрялся резать значение переменной, и в запрос уходило уже не то значение, которое запрашивалось, а подрезанное.

select forceliterals currency
where currency.CurrencyCode == "XXXY"

Дал ожидаемый результат (ничего не вернул).

Возможно, и в вашем случае можно поближе докопаться до причины.
__________________
С уважением,
glibs®
Старый 10.11.2008, 13:53   #7  
miklenew is offline
miklenew
Участник
Аватар для miklenew
MCBMSS
1C
Лучший по профессии 2009
 
1,688 / 433 (18) +++++++
Регистрация: 10.07.2006
Адрес: г. Ликино-Дулёво
Цитата:
Сообщение от Logger Посмотреть сообщение
Вы сперва профайлером посмотрите- запрос на БД какой-нить уходит вообще или нет.
Уходит. Если бы не уходил, InventTrans бы не было.
X++:
SELECT /*+ INDEX(A I_177OPENITEMIDX) INDEX(B I_698DIMIDIDX) ORDERED */A.ITEMID,A.STATUSISSUE,A.DATEPHYSICAL,A.QTY,A.COSTAMOUNTPOSTED,A.CURRENCYCODE,A.TRANSTYPE,A.TRANSREFID,A.INVOICEID,A.VOUCHER,A.DATEEXPECTED,A.DATEFINANCIAL,A.COSTAMOUNTPHYSICAL,A.INVENTTRANSID,A.STATUSRECEIPT,A.PACKINGSLIPRETURNED,A.INVOICERETURNED,A.PACKINGSLIPID,A.VOUCHERPHYSICAL,A.COSTAMOUNTADJUSTMENT,A.QTYSETTLED,A.COSTAMOUNTSETTLED,A.VALUEOPEN,A.DIRECTION,A.DATESTATUS,A.COSTAMOUNTSTD,A.DATECLOSED,A.DEL_CONFIGID,A.INVENTTRANSIDFATHER,A.COSTAMOUNTOPERATIONS,A.ITEMBOMID,A.INVENTTRANSIDRETURN,A.PROJID,A.PROJCATEGORYID,A.INVENTDIMID,A.INVENTDIMFIXED,A.DATEINVENT,A.CUSTVENDAC,A.TRANSCHILDREFID,A.TRANSCHILDTYPE,A.REVENUEAMOUNTPHYSICAL,A.ASSETID,A.PROJADJUSTREFID,A.DEL_TAXAMOUNTPHYSICAL,A.ASSETBOOKID,A.INVENTREFTRANSID,A.CORRECT,A.GM_LEDGERCORRECT,A.COMPENSATE,A.IMPRESERVETYPE,A.MRD_INVENTREFTRANSID,A.MODIFIEDDATE,A.MODIFIEDTIME,A.MODIFIEDBY,A.CREATEDDATE,A.CREATEDTIME,A.CREATEDBY,A.RECVERSION,A.RECID
FROM INVENTTRANS A,INVENTDIM B
WHERE ((SUBSTR(NLS_LOWER(A.DATAAREAID),1,3)=NLS_LOWER(:IN1))
AND (((((((SUBSTR(NLS_LOWER(A.ITEMID),1,30)=NLS_LOWER(:IN2))
AND (A.VALUEOPEN=:IN3))
AND (A.STATUSRECEIPT>=:IN4))
AND (A.STATUSRECEIPT<=:IN5))
AND (A.STATUSISSUE>=:IN6))
AND (A.STATUSISSUE<=:IN7))
AND (A.DATEFINANCIAL<=:IN8)))
AND ((SUBSTR(NLS_LOWER(B.DATAAREAID),1,3)=NLS_LOWER(:IN9))
AND (((SUBSTR(NLS_LOWER(B.INVENTDIMID),1,30)=SUBSTR(NLS_LOWER(A.INVENTDIMID),1,30))
AND (SUBSTR(NLS_LOWER(B.INVENTLOCATIONID),1,18)=NLS_LOWER(:IN10)))
AND (SUBSTR(NLS_LOWER(B.INVENTDIMDEFECT),1,10)=NLS_LOWER(:IN11))))
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему.
Старый 10.11.2008, 14:21   #8  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Я думал у вас результат из кеша берется. В таком случае возможно получение результата без обращения к БД.
Старый 10.11.2008, 14:24   #9  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Вообще-то, смысл хинта forcePlaceholders заключается в том, что SQL-сервер должен использовать ранее сформированный план для аналогичного запроса изменяя только параметр.

Соответственно хинт forceLiterals имеет противоположный смысл. Не использовать ранее сформированный план запроса, а каждый раз заново формировать этот план.

Т.е. эти хинты должны влиять только на повторные запросы и только в том случае, если на сервере еще сохранился план выполнения аналогичного запроса исполненного ранее. Имеет смысл при выполнении запросов в цикле.

Запрос, разумеется, будет посылаться на сервер в любом случае. Вопрос в том, с какими параметрами. Т.е. смотреть надо не на запрос, а на переданные параметры.

Вероятно, Oracle в плане запроса как-то кеширует еще и возможные значения параметров (тип, размер)?
Старый 10.11.2008, 14:26   #10  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от glibs Посмотреть сообщение
Наблюдал похожий глюк именно на Oracle (на MS SQL не удалось тогда воспроизвести).
Запрос наверно как Query был составлен ? Потому что если использвали статический SQL в X++ то он должен требовать переменную с фиксированной длиной, а для них автоматически усекается строка.

Либо возможно глюк в этом и состоял, что из неправильного кода путем усечения
в условии
currency.CurrencyCode == "XXXY"
на месте "XXXY" стояла переменная со значением "ХХХ" - но это уже глюк программиста X++
Старый 10.11.2008, 15:08   #11  
glibs is offline
glibs
Member
Сотрудники компании It Box
Most Valuable Professional
Лучший по профессии 2011
Лучший по профессии 2009
 
4,942 / 911 (40) +++++++
Регистрация: 10.06.2002
Адрес: I am from Kyiv, Ukraine. Now I am in Moscow. For private contacts: glibs@hotmail.com
Цитата:
Сообщение от Logger
...
Запрос наверно как Query был составлен ?
...
Нет.
Цитата:
Сообщение от Logger
...
но это уже глюк программиста X++
...
Я тестировал на джобе. Иначе фиг такое отловишь. В условии писал строку, а не переменную. Это какая-то особенность Ораклиного движка. Код валюты в БД определен как трехсимвольная строка. И при placeholders, видать, он режет input. Если это знать и учесть, то в принципе не проблема. Просто нужно знать.
__________________
С уважением,
glibs®
Старый 10.11.2008, 15:34   #12  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от glibs Посмотреть сообщение
Нет.

Я тестировал на джобе. Иначе фиг такое отловишь. В условии писал строку, а не переменную. Это какая-то особенность Ораклиного движка. Код валюты в БД определен как трехсимвольная строка. И при placeholders, видать, он режет input. Если это знать и учесть, то в принципе не проблема. Просто нужно знать.
Хм. Любопытно.
Мне кажется что когда указываешь константу он просто приводит её неявным преобразованием типов к нужной длине, как например при присваивании строковых переменных с разной длиной.
Старый 10.11.2008, 17:46   #13  
petergunn is offline
petergunn
Участник
 
118 / 274 (10) ++++++
Регистрация: 30.08.2005
Адрес: Tyumen
Цитата:
Сообщение от Logger Посмотреть сообщение
Хм. Любопытно.
Мне кажется что когда указываешь константу он просто приводит её неявным преобразованием типов к нужной длине, как например при присваивании строковых переменных с разной длиной.
В этой ветке Непонятка с exist join-ом... пост gl00mie практически объясняет такое поведение запроса на движке Oracle.

Цитата:
Сообщение от gl00mie
Был аналогичный косяк, правда, на Oracle с его NSL_LOWER(), SUBSTR() и прочими функциями. В частности, при работе с Oracle из строковых полей вырезаются подстроки длины EDT. Так вот, пытался я join'ить по InventTrans.TransRefId = InventJournalTable.JournalId, и тоже ничего не работало; дело оказалось в том, что у EDT JournalId и InventTransRefId разная длина, в результате на СУБД уходил запрос вида

PHP код:
WHERE SUBSTR(NLS_LOWER(A.TransRefId),1,20)=SUBSTR(NLS_LOWER(B.JournalId),1,10
Похоже что начиная с 4.0 для управления таким поведением ввели опцию "Include SUBSTR and LOWER in all SELECT statements to support Oracle mixed-case systems" в Autogeneration Options конфигурационной утилиты сервера AOS:
Изображения
 

Последний раз редактировалось petergunn; 10.11.2008 в 17:51.
Старый 10.11.2008, 19:42   #14  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Неее. Там немного другой случай.
Там джоин двух таблиц, а с точки зрения SQL строковые типы разной длины - это разные типы.

А здесь именно параметр запроса.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Вопрос по модулю Расчеты с персоналом. Выплата заработной платы. Keks DAX: Функционал 7 28.12.2009 10:31
Вопрос по созданию отчета asd1274 DAX: Программирование 6 05.12.2008 21:44
Вопрос по Проектам PSA DAX: Функционал 35 19.01.2007 22:26
Еще вопрос про покрытие по аналитикам в Сводном планировании rt2 DAX: Функционал 3 24.03.2006 18:56
расчеты с персоналом. НДФЛ. вопрос чайника shumelka DAX: Функционал 2 25.03.2004 11:36
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

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

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