18.07.2012, 14:26 | #1 |
MCT
|
Коллеги, что вы думаете о данном коде?
Этот табличный метод
X++: static void updateParent(InventoryGuidInvoice inventoryGuidInvoice) { InventoryGuid current, parent; InventoryGuidInvoice parentDistr; InvGuid InvGuid; ; InvGuid = inventoryGuidInvoice.InvGUID; ttsbegin; WHILE(TRUE) { SELECT FIRSTONLY current WHERE current.InvGuid == InvGUID; InvGUID = current.ParentInvGUID; SELECT FIRSTONLY parent WHERE current.ParentInvGUID == parent.InvGUID; if(parent) { //parentDistr.disableCache(); SELECT FIRSTONLY FORUPDATE parentDistr WHERE parentDistr.InvGUID == InvGUID && parentDistr.TransRecId == inventoryGuidInvoice.TransRecId //........... && parentDistr.JuridicalPersonId == inventoryGuidInvoice.JuridicalPersonId; if(parentDistr) { parentDistr.AMOUNTCUR += inventoryGuidInvoice.AmountCur;//слияние к предку //....... parentDistr.Update(); } else { parentDistr.data(InventoryGuidInvoice); parentDistr.InvGUID = parent.InvGUID; parentDistr.insert(); } } else { break; } current.clear(); } ttscommit; }
__________________
Axapta book for developer |
|
18.07.2012, 15:07 | #2 |
Участник
|
а что вас в нем смущает? код пробегает по цепочке "вверх" и что то апдейтит или создает. Оформление конечно страдает
Последний раз редактировалось ice; 18.07.2012 в 15:10. |
|
18.07.2012, 15:20 | #3 |
MCT
|
Вы тоже так пишите?
Я хочу услышать мнения коллег, насколько так вообще корректно писать. Или может у меня одного глаз замылился.
__________________
Axapta book for developer Последний раз редактировалось MikeR; 18.07.2012 в 15:27. |
|
18.07.2012, 15:44 | #4 |
MCITP
|
Цитата:
Ну по крайней мере я бы использовал рекурсию... OFFTOP: не знал, что PL\SQL Formatter можно к Х++ прикрутить...
__________________
Zhirenkov Vitaly Последний раз редактировалось ZVV; 18.07.2012 в 15:44. Причина: синтаксис |
|
|
За это сообщение автора поблагодарили: MikeR (2). |
18.07.2012, 15:57 | #5 |
Участник
|
Если не касаться оформления, а именно верхних регистров SQL-операторов (лично для меня это непривычно), то while(true) в сочетании с break'ом - это очень "плохой тон", мягко говоря, в программировании в целом (не говоря уже о табличном методе в Ax), о чем, кстати, упоминал в своей книге "Совершенный код" Стив Макконнелл.
ИМХО, следует все же изучить связи таблиц и перестроить данный запрос на while select в сочетании с join'ом, пусть даже с внутренним select'ом. Даже вложенный while не так бьет по глазам, как while(true), хотя это тоже не есть хорошо.
__________________
С уважением, Александр. |
|
|
За это сообщение автора поблагодарили: MikeR (2). |
18.07.2012, 15:58 | #6 |
MCT
|
Коллеги, вы не поверите, но суть в том, что цикл вообще не нужен.
X++: WHILE(TRUE) Я подумал, что это очевидно.....
__________________
Axapta book for developer |
|
18.07.2012, 15:59 | #7 |
Участник
|
Слов нет, одни эмоции Вспомнились комментарии в ководстве к одному "шедевру":
Цитата:
Буааууеееееееееее! Ааааа! Глаза кровоточат!
|
|
|
За это сообщение автора поблагодарили: MikeR (2), jeky (2), someOne (8). |
18.07.2012, 16:07 | #8 |
Участник
|
Кстати, да. О чем и говорит firstonly. А теперь и мне стало интересно, зачем так было сделано - "запускать выполнение" таким образом?
__________________
С уважением, Александр. |
|
18.07.2012, 16:08 | #9 |
MCITP
|
Цитата:
Он нужен для того что бы запускать и следующие итерации тоже, а не только первую. Цикл будет выполнятся, кока не закончится дерево (не будет парента) и сработает брэйк. Ну собственно такая эмуляция рекурсии...
__________________
Zhirenkov Vitaly |
|
|
За это сообщение автора поблагодарили: S.Kuskov (1). |
18.07.2012, 16:20 | #10 |
Axapta
|
Почему? По-моему, это такой обход дерева. И без "while true" работать не будет. При каждой итерации меняется InvGUID и цикл прервется только тогда, когда не найдется parent. И "while true" при таком написании кода очень даже нужен. Понятно, что код можно переписать иначе.
|
|
18.07.2012, 16:20 | #11 |
MCT
|
Собственно да, человек запускает перебор (чтобы более корректно было), но в других местах это вообще не требуется.
Используется конструкция X++: while select forupdate ... {} X++: while select { ttsbegin; select forupdate ttscommit; }
__________________
Axapta book for developer |
|
18.07.2012, 16:25 | #12 |
MCT
|
Кстати, а действительно кто-нибудь пишет рекурсию через
X++: while (true)
__________________
Axapta book for developer |
|
18.07.2012, 16:29 | #13 |
MCT
|
Да дело в том, что не для всех это понятно.
__________________
Axapta book for developer |
|
18.07.2012, 16:30 | #14 |
Axapta
|
|
|
18.07.2012, 16:31 | #15 |
Участник
|
ИМХО, рекурсию лучше организовывать через отдельно написанную функцию внутри метода.
__________________
С уважением, Александр. Последний раз редактировалось samolalex; 18.07.2012 в 16:33. Причина: 111 |
|
18.07.2012, 16:35 | #16 |
Участник
|
Цитата:
Сообщение от MikeR
Собственно да, человек запускает перебор (чтобы более корректно было), но в других местах это вообще не требуется.
Используется конструкция X++: while select forupdate ... {} X++: while select { ttsbegin; select forupdate ttscommit; } Вы хотите поломать целостность данных?
__________________
Axapta v.3.0 sp5 kr2 |
|
18.07.2012, 16:37 | #17 |
MCITP
|
Цитата:
Сообщение от MikeR
Собственно да, человек запускает перебор (чтобы более корректно было), но в других местах это вообще не требуется.
Используется конструкция X++: while select forupdate ... {} X++: while select { ttsbegin; select forupdate ttscommit; }
__________________
Zhirenkov Vitaly |
|
18.07.2012, 16:39 | #18 |
MCT
|
Олег, там используется перебор коллекции
X++: while (mi.....more())
__________________
Axapta book for developer |
|
18.07.2012, 16:43 | #19 |
MCT
|
X++: table t1,t2; ttsbegin; while select t1 { select forupdate t2 where t2.recid == t1.RecId; ..... t2.update(); } ttscommit;
__________________
Axapta book for developer Последний раз редактировалось MikeR; 18.07.2012 в 16:45. |
|
18.07.2012, 16:52 | #20 |
Axapta
|
Цитата:
X++: while (true) { if (bomTableMove.RecId == bomTableDrop.RecId) { dropParent = tree.getParent(curParent); bomTableDropParent = node2BOMTable.lookup(dropParent); return bomTableMoveParent.RecId != bomTableDropParent.RecId || dropParent == rootId; } else { curParent = tree.getParent(curParent); if (curParent == rootId) return true; bomTableDrop = node2BOMTable.lookup(curParent); } } |
|
|
|