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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 02.06.2010, 11:22   #1  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Блокировать Select
Делаю примерно такую выборку со вставкой:
X++:
    ttsbegin;
    while select forUpdate markupTrans
          where markupTrans.transTableId == vendInvoiceJour.tableId  &&
                markupTrans.transRecId   == vendInvoiceJour.recId
    {
            markupTransNew.clear();
            markupTransNew.data(markupTrans);
            markupTransNew.Value = (  );
            markupTransNew.lineNum = MarkupTrans::lastLineNum(markupTransNew.transTableId, markupTransNew.transRecId) + 1;
            markupTransNew.insert();
            markupTrans.delete();
        }
    }
Я не хочу чтобы добавленная в цикле запись попала ввыборку, хотя она и удовлетворяет условиям в while select..
Так вот под разными пользователями аксапта ведет себя по разному на одних и тех же данных. У одних зацикливается, а под моим делает вставку удаление и выходит нормально.
Я конечно перепишу код учитывая глюк, но всетаки интересно знать что на этот счет говорить теория?
Старый 02.06.2010, 11:46   #2  
ice is offline
ice
Участник
Аватар для ice
Лучший по профессии 2014
 
1,731 / 406 (17) +++++++
Регистрация: 23.03.2006
а почему просто не проапдейтить?
Старый 02.06.2010, 12:00   #3  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от ice Посмотреть сообщение
а почему просто не проапдейтить?
Я говорю, что вариантов переписать много. Дело не в этом.
Просто на самом деле у меня всталяется много записей в туже таблицу. Среди них может появиться та которая удовлетворит внешнему запросу. Что бы не писать всякие провеки где инсерт, а где апдейт я решил сделать более внятно на мой взгляд. Вставить все что нужно и убрать лишнее в конце.

На самом деле удаление можно и убрать, но вставленная запись всеравно попадет в выборку и вызовет зацикливание.
Старый 02.06.2010, 12:01   #4  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
X++:
while select forUpdate markupTrans order by RecId desc
курсор у нас динамический, так что принудительная сортировка по убыванию RecId не даст попасть в него новым записям
__________________
-ТСЯ или -ТЬСЯ ?
За это сообщение автора поблагодарили: Logger (3), S.Kuskov (3).
Старый 02.06.2010, 18:34   #5  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
Цитата:
Сообщение от Vadik Посмотреть сообщение
X++:
while select forUpdate markupTrans order by RecId desc
курсор у нас динамический, так что принудительная сортировка по убыванию RecId не даст попасть в него новым записям
А если во время операции recId перевалит через maxInt()? Для 3.0. Это, конечно, не очень вероятно, но вполне возможно.

Да даже не обязательно во время. Если в выбору попадут и положительные и отрицательные recId, то такой селект уже не сработает в том плане, что вновь создаваемые записи будут попадать в "середину". Или я чего-то не понял?
Старый 02.06.2010, 12:16   #6  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Вот ещё похожая тема Как должен работать такой запрос
Старый 02.06.2010, 17:39   #7  
titov is offline
titov
Участник
 
73 / 87 (3) ++++
Регистрация: 23.12.2005
Адрес: Казань
Две ошибки в коде1. markupTransNew.data(markupTrans); - после такой команды надо сделать markupTransNew.recid = 0; - это мелочь, но советую эту команду применять наравне с markupTransNew.clear();2. Зацикливание неизбежно. Условие выборки включает вновь создаваемые записи. Можно конечно ловить новые записи разными ухищрениями, но лучше делать по рекомендациям поставщика программы - см ниже
X++:
void copyBOM(BOMId _FromBOM, BOMId _ToBOM)
{
    RecordInsertList BOMList;
    BOM BOM, newBOM;
    ;
    BOMList = new RecordInsertList(tableNum(BOM));
    while select BOM    where BOM.BOMId == _FromBOM
    {
        newBOM.data(BOM);
        newBOM.BOMId = _ToBOM;
        BOMList.add(newBOM);
    }
    BOMList.insertDatabase();
}
И еще совет - если внутри цикла по курсору идет обновление, удаление, запись по той же самой таблице, что присутствет в выборке (select, query) всегда создавать массив (например приведенный класс, класс MAP, SET (аккуратно - это ссылки а не сами записи) ) и только после выхода из цикла выполнить комит в базе - просто, но надежно защитит вас в будущем от непонятных глюков. Еще на многих таблицах есть метод findRecid - это еще один вариант - идем по циклу выборки для чтения - в контейнер recid и newValue - потом во втором цикле - обновление.
Старый 03.06.2010, 07:58   #8  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от titov Посмотреть сообщение
X++:
void copyBOM(BOMId _FromBOM, BOMId _ToBOM)
{
    RecordInsertList BOMList;
    BOM BOM, newBOM;
    ;
    BOMList = new RecordInsertList(tableNum(BOM));
    while select BOM    where BOM.BOMId == _FromBOM
    {
        newBOM.data(BOM);
        newBOM.BOMId = _ToBOM;
        BOMList.add(newBOM);
    }
    BOMList.insertDatabase();
}
.
В данном примере всталяемые и выбираемые записи не предполагают пересечение.
RecordInsertList в моем случае не совсем подходит потому как add() тоже вставляет в базу записи. Не сразу, пачками както, но тем неменее в общем случае не подходит.
Старый 03.06.2010, 09:56   #9  
CDR is offline
CDR
MCTS
MCBMSS
 
236 / 175 (6) ++++++
Регистрация: 27.11.2003
Цитата:
Сообщение от Perc Посмотреть сообщение
Я конечно перепишу код учитывая глюк, но всетаки интересно знать что на этот счет говорить теория?
Теория на этот счет говорит, что Ваш код содержит логическую ошибку. Как вы проектировали алгоритм, когда у Вас в цикле выборки записей вставляются в таблицу новые записи, влияющие на результат выборки?
Это как если бы для цикла for(i) внутри самого цикла присваивать i новое значение, а потом удивляться и обсуждать странное поведение цикла.
__________________
Dynamics AX Experience

Последний раз редактировалось CDR; 03.06.2010 в 10:05.
Старый 03.06.2010, 14:40   #10  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от CDR Посмотреть сообщение
..Это как если бы для цикла for(i) внутри самого цикла присваивать i новое значение, а потом удивляться и обсуждать странное поведение цикла.
Ну все таки for это не совсем курсор БД. Да и for бывает разный). В свое время сталкивался с реализацией цикла (не в аксапте). Конструкция типа (i=1; i<=x; i++). В теле цикла менял x, а оказалось что сравнивалось всеравно с первоначальным значением x.
Ну в общем спасиба, понял, что никаих заклинаний для курсоров нет. будем писать правильно))
Теги
курсор

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
2 while select или join? _scorp_ DAX: Программирование 9 23.01.2009 16:02
Разница NotInTTS и Found Logger DAX: База знаний и проекты 6 18.09.2008 12:35
gatesasbait: Reverse keyword on Select Statements Blog bot DAX Blogs 0 08.02.2008 00:10
Fred Shen: Always use recId to know if a select statement returns a record Blog bot DAX Blogs 0 28.10.2006 16:40
Вопрос про Demand Planner slava09 DAX: Функционал 4 25.09.2006 11:43

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

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

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