14.04.2007, 12:19 | #1 |
Участник
|
не срабатывает select forupdate для joined таблицы?
Dynamics AX 3.0 SP5 KR2
SQL Server 2005 Запрос следующего вида: X++: static void Job37(Args _args) { SalesTable salesReservePhysical; InventTrans inventTransIssue; InventDimParm inventDimParm; InventDim inventDim; InventDim inventDimCriteria; ; ttsbegin; select salesReservePhysical order by CustAccount join forupdate inventTransIssue order by InventTransId where inventTransIssue.TransType == InventTransType::Sales && inventTransIssue.TransRefId == salesReservePhysical.SalesId && //salesReservePhysical.Active == NoYes::Yes && inventTransIssue.itemId == '140' && inventTransIssue.valueOpen == InventTransOpen::Yes && inventTransIssue.statusReceipt == StatusReceipt::None && inventTransIssue.statusIssue == StatusIssue::ReservOrdered && //inventTransIssue.inventTransId != movement.transId() && inventTransIssue.inventRefTransId == '' #inventDimJoin(inventTransIssue.InventDimId,inventDim,inventDimCriteria,inventDimParm,DimIdIdx); while (inventTransIssue) { inventTransIssue.statusIssue = StatusIssue::ReservPhysical; //inventTransIssue.inventDimId = _inventDim.inventDimId; inventTransIssue.update(); next inventTransIssue; } ttscommit; } Так вот, в запросе хочу InventTrans выбрать на обновление. А вот запрос, который получаю в профайлере: Оператор SQL: (SalesTable,InventTrans,InventDim) SELECT A.SALESID,…,A.CREATEDBY,A.RECVERSION,A.RECID,B.ITEMID,B.STATUSISSUE,…,B.RECID FROM SALESTABLE A,INVENTTRANS B,INVENTDIM C WHERE (A.DATAAREAID='dat') AND ((B.DATAAREAID='dat') AND (((((((B.TRANSTYPE=0) AND (B.TRANSREFID=A.SALESID)) AND (B.ITEMID='140')) AND (B.VALUEOPEN=1)) AND (B.STATUSRECEIPT=0)) AND (B.STATUSISSUE=5)) AND (B.INVENTREFTRANSID=' '))) AND ((C.DATAAREAID='dat') AND (C.INVENTDIMID=B.INVENTDIMID)) OPTION(FAST 5) [Идентификатор=5344, Использовано повторно=Нет] Конкретно мой случай: Оператор SQL: (ZCH_SalesReservePhysical,InventTrans,InventDim) SELECT A.PRIORITY,A.ACTIVE,A.SALESID,A.RECVERSION,A.RECID,B.ITEMID,…,B.RECID FROM ZCH_SALESRESERVEPHYSICAL A WITH( NOLOCK),INVENTTRANS B WITH( NOLOCK),INVENTDIM C WITH( NOLOCK) WHERE (A.DATAAREAID='dat') AND ((B.DATAAREAID='dat') AND (((((((((B.TRANSTYPE=0) AND (B.TRANSREFID=A.SALESID)) AND (A.ACTIVE=1)) AND (B.ITEMID='140')) AND (B.VALUEOPEN=1)) AND (B.STATUSRECEIPT=0)) AND (B.STATUSISSUE=5)) AND (B.INVENTTRANSID<>' ЛОТ054717')) AND (B.INVENTREFTRANSID=' '))) AND ((C.DATAAREAID='dat') AND ((C.INVENTDIMID=B.INVENTDIMID) AND (C.INVENTLOCATIONID='КВ-ПЛД-РЦ'))) ORDER BY A.DATAAREAID,A.PRIORITY,B.DATAAREAID,B.INVENTTRANSID OPTION(FAST 18,FORCE ORDER) [Идентификатор=11907, Использовано повторно=Нет] И, собственно вопросы: 1. Как выбрать InventTrans с UPDLOCK, сохранив сортировку в указанном порядке? 2. Почему в InventDim ничего не выбирается (и в Аксапте RecId = 0), хотя в дебаггере явно вижу, что должна были отобраться записи с учетом склада (только одна аналитика активна) ЗЫ. Возможно я просто что-то в упор не вижу? Второй вопрос - чисто из интереса. На самом деле интересует ответ именно на первый Последний раз редактировалось kashperuk; 14.04.2007 в 12:25. Причина: ЗЫ |
|
14.04.2007, 12:35 | #2 |
Участник
|
Даа. Еще печальней.
NEXT же нельзя использовать для приджойненых курсоров - придется как-то сильно переделывать все. А так не хотелось Но вопросы в принципе в силе! |
|
14.04.2007, 13:47 | #3 |
Участник
|
почему нельзя просто:
X++: while select ... попробуйте установить флаг `forupdate` во всех/первой таблице. |
|
14.04.2007, 14:00 | #4 |
Участник
|
Да я уже переделал по-другому.
если сделать выборку на обновление по всем полям, то отратабывает нормально выборка. Но позже все равно вылетело бы на next - потому что это получается заджойненый курсор. Из-за этого собственно и пришлось переделать. Изначально просто хотел минимально отклоняться от уже написанного кода. Это про метод: Classes\InventUpdate\updateDimReservePhysical |
|
16.04.2007, 09:47 | #5 |
MCTS
|
X++: ttsbegin; while select forupdate firstTable join secondTable where secondTable.ItemId == firstTable.ItemId { secondTable.field_1 = 1; secondTable.field_2 = 2; secondTable.update(); } ttscommit;
__________________
В глухомани, в лесу Несмотря на красу Дни проводит Лиса Патрикевна. Я никак не пойму Отчего, почему Не пускают куму На деревню |
|
16.04.2007, 10:34 | #6 |
Участник
|
:)
Так то конечно будет работать.
Интересовала ситация именно с выбором на обновление и LOCK только второго курсора. Но и это уже не очень актуально. |
|
05.12.2008, 00:11 | #7 |
MCITP
|
подниму старую тему, с вашего позволения...
Так можно ли всё-таки в аксе сделать join и выбрать на редактирование только одну (например) таблицу? Аналогов SQL, типа X++: select ... for update of ... Может в 2009 или дальше что-то изменилось или хотя бы планируется? Откуда возник вопрос: есть ряд запросов типа (возможно с сортировкой) X++: select forUpdate inventTrans where ... join InventDim where ... select forUpdate inventSum where ... join InventDim where ... Ясен пень, что блокировать InventDim по смыслу здесь не нужно. Но как это сделать не понятно. Разбивать на 2 запроса часто не представляется возможным по причинам либо сортировки, либо производительности, либо ещё чего-то... А блокировочки то жить очень иногда мешают...
__________________
Zhirenkov Vitaly |
|
05.12.2008, 08:06 | #8 |
Member
|
Цитата:
Сообщение от ZVV
...
Так можно ли всё-таки в аксе сделать join и выбрать на редактирование только одну (например) таблицу? ...
__________________
С уважением, glibs® |
|
05.12.2008, 09:31 | #9 |
NavAx
|
Цитата:
Так можно ли всё-таки в аксе сделать join и выбрать на редактирование только одну (например) таблицу?
|
|
05.12.2008, 10:18 | #10 |
----------------
|
другой вариант. Выбирать без обновления, а уже в цикле делать какой-дь find(, true)
|
|
05.12.2008, 10:27 | #11 |
MCITP
|
в оракле - да (см. моё предыдущее сообщение, в MS SQL - незнаю, не уверен).
__________________
Zhirenkov Vitaly |
|
05.12.2008, 10:31 | #12 |
MCITP
|
как вариант - да, но плохо что при этом придётся ещё раз выбирать inventDim, т.к. данные из него обычно нужны.
Цитата:
Лучше уже предыдущий вариант озвученный raz.
__________________
Zhirenkov Vitaly |
|
05.12.2008, 10:31 | #13 |
Модератор
|
Согласен с ZVV - я бы сделал метод на обновляемой таблице, потом вызывал бы его - пусть бы он на сервере и шуршал.
С Уважением, Георгий |
|
05.12.2008, 10:42 | #14 |
MCITP
|
Цитата:
С чем конкретно согласен и можно ли поподробнее про метод на таблице?
__________________
Zhirenkov Vitaly |
|
05.12.2008, 10:50 | #15 |
----------------
|
ZVV, Вы будете смеяться, но именно по этой идеологи и работает Акс4... ну и наверно 2009
ибо в нету (не работает) forupdate в 4ке (на MS SQL) |
|
05.12.2008, 10:52 | #16 |
Модератор
|
Да я за эту фразу зацепился:
Цитата:
Либо лист обработал бы в классе (как в FormLetter сделано). С Уважением, Георгий |
|
05.12.2008, 10:58 | #17 |
MCITP
|
Цитата:
Там действительно forUpdate не идёт в базу, а потом проверяется совпадение recVersion на момент обновления. Если на таблицах убрать оптимистичную блокировку (или "хинтами" в запросе), то всё будет как и в тройке.
__________________
Zhirenkov Vitaly |
|
05.12.2008, 11:17 | #18 |
----------------
|
согласен, можно отключить, но поумолчанию оно включено и такое поведение считается правильным
то есть большинство запросов выполняется именно так.. выборка без блокировок с обновлением "на удачу" |
|
05.12.2008, 12:00 | #19 |
MCITP
|
Цитата:
Но не реализовывть же мне этот механихм на 3-ке.
__________________
Zhirenkov Vitaly |
|