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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 13.09.2011, 19:19   #1  
Alexius is offline
Alexius
Участник
Аватар для Alexius
 
461 / 248 (9) ++++++
Регистрация: 13.12.2001
Бага в Query update(true)
AX2009 SP1 RU7 / MS SQL 2008 R2

При формировании обновляемого запроса в некоторых случаях происходит двойное обновление записи. Задваиваться могут как все записи, так и часть. Полной логики я не смог раскопать, но это как-то связано с индексами. Ниже привожу пример с которым я возился, вместо "Номенлатурная Группа" нужно подставить вашу группу с числом элементов не менее 20. Далее, если все индексы штатные, то у меня получается предсказуемый вариант поведения, т.е. кол-во обновляемых записей равно числу записей в запросе. Для получения задвоения необходимо в индексе InventTable / GroupItemIdx поле ItemId заменить на ItemName, после этого у меня на некоторых группах происходят двойные обновления. В 3-ке SP4 на аналогичных данных все ОК.

X++:
static void DEV_QueryUpdateBag(Args _args)
{
    Query                   query = new Query();
    QueryRun                queryRun;
    QueryBuildDataSource    qbds;
    InventTable             inventTable;
    int                     sel, upd, i;
    container               c;
    ;

    qbds = query.addDataSource(tablenum(InventTable));
    qbds.addRange(fieldnum(InventTable, ItemGroupId)).value("Номенлатурная Группа");
    qbds.update(true);

    queryRun = new QueryRun(query);

    while (queryRun.next())
    {
        sel++;
    }
    
    queryRun = new QueryRun(query);

    ttsbegin;
    
    while (queryRun.next())
    {
        inventTable = queryRun.get(tablenum(InventTable));

        if (confind(c, inventTable.ItemId))
            info (strfmt("%1 %2 %3", i, inventTable.ItemId, inventTable.ItemName));
        else
        {
            c += inventTable.ItemId;
            i++;
        }

        inventTable.ItemName  = inventTable.ItemName + ".";
        inventTable.doUpdate();

        upd++;
    }
    
    ttsabort;
    
    info(strfmt("SELECT %1 UPDATE %2 DELTA %3", sel, upd, upd-sel));
}
Старый 13.09.2011, 22:45   #2  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,941 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Было чо-то похожее в 3-ке
Как работает queryRun
Старый 14.09.2011, 08:49   #3  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Alexius Посмотреть сообщение
Для получения задвоения необходимо в индексе InventTable / GroupItemIdx поле ItemId заменить на ItemName, после этого у меня на некоторых группах происходят двойные обновления.
Мне кажется это принципиальный момент. Скорее всего при выборе данных запрос использует этот индекс. В момент изменения ItemName содержащий это поле индекс перестраивается. Создаётся впечатление, что запрос не учитывает это перестроение индекса. Что-то вроде этой проблемы: Как должен работать такой запрос Если это так, то это явный баг.
Ещё, если я не ошибаюсь, на форуме как-то проскакивала информация о том что в случае использования QueryRun работа с курсором происходит через вспомогательные хранимые процедуры (попробую сейчас найти). Может это в них собака порылась?
Старый 14.09.2011, 10:20   #4  
Alexius is offline
Alexius
Участник
Аватар для Alexius
 
461 / 248 (9) ++++++
Регистрация: 13.12.2001
Цитата:
Сообщение от Logger Посмотреть сообщение
Было чо-то похожее в 3-ке
Как работает queryRun
Похожее, но не то. Эта проблема возникает при линковании нескольких таблиц, а в моем случае при формировании запроса на обновление.

PS. Об этом приколе я помню

PS2. А у кого нибудь еще воспроизвелась описанная выше бага ?

Последний раз редактировалось Alexius; 14.09.2011 в 10:25.
Старый 14.09.2011, 12:57   #5  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Alexius Посмотреть сообщение
MS SQL 2008 R2
Для получения задвоения необходимо в индексе InventTable / GroupItemIdx поле ItemId заменить на ItemName, после этого у меня на некоторых группах происходят двойные обновления.
Вообще это напоминает старую багу в SQL Server, см. kb843267 - Dynamic cursor retrieves the same row two times when you update the non-clustered index key to the same value
Цитата:
A dynamic cursor retrieves the same row two times when all the following conditions are true:
  • The dynamic cursor has an order-by clause that matches a non-clustered index.
  • One or more key columns is updated to the same value that the column currently has. The key columns in the non-clustered index are used to specify order.
  • One or more key columns can be assigned a null value
Впрочем, дело еще может быть в кэшировании. Воспроизведется ли ошибка, если то же самое сделать через while select forupdate? А если перед этим у табличного буфера вызвать disableCache(true)?
За это сообщение автора поблагодарили: Alexius (3).
Старый 14.09.2011, 14:09   #6  
Alexius is offline
Alexius
Участник
Аватар для Alexius
 
461 / 248 (9) ++++++
Регистрация: 13.12.2001
Цитата:
Сообщение от gl00mie Посмотреть сообщение
Воспроизведется ли ошибка, если то же самое сделать через while select forupdate? А если перед этим у табличного буфера вызвать disableCache(true)?
1. InventTable CacheLookup = Found
1.1 Update Field ItemName
1.1.1 Query False
1.1.2 while select forupdate False
1.2 Update Field NameAlias
1.2.1 Query False
1.2.2 while select forupdate OK
2. InventTable CacheLookup = None
2.1 Update Field ItemName
2.1.1 Query False
2.1.2 while select forupdate OK
2.2 Update Field NameAlias
2.2.1 Query False
2.2.2 while select forupdate OK
Цитата:
Сообщение от gl00mie Посмотреть сообщение
Вообще это напоминает старую багу в SQL Server
Исходно база была на уровне совместимости 2008 (100)
1. Перевел базу на уровень совместимости 2000 (80) (остановил АОС, отсоединил/присоединил базу, стартанул АОС)
Оба варианта ОК
2. Вернул аналогично на уровень 2008 (100)
Оба варианта ОК

Вот такое дежавю

PS. Вечерочком попробую рестартовать полностью сервант и посмотреть
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
AIF: OData Query Service Blog bot DAX Blogs 0 24.08.2011 09:11
fatihdemirci: CrossCopmany ile query yazmak Blog bot DAX Blogs 0 17.08.2010 16:05
jinx: Dynamics AX – Query-Ranges und Filtereinstellungen des Benutzers Blog bot DAX auf Deutsch 0 04.02.2010 00:05
Dynamics AX Geek: Using query() Blog bot DAX Blogs 0 04.05.2009 14:05
update_recordset. Бага или фича? Lucky13 DAX: Программирование 7 08.04.2009 17:33
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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