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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 01.09.2008, 10:22   #1  
koraman is offline
koraman
Участник
 
41 / 11 (1) +
Регистрация: 12.02.2008
Адрес: Казань
Цитата:
Сообщение от belugin Посмотреть сообщение
а что на сервер уходит? вообще непонятно зачем так делать, потому, что x + NULL = NULL
Как посмотреть, что уходит на сервер?
Это было бы удобно, например, когда для каждого клиента надо вывести суммарный оборот.

Цитата:
Сообщение от NNB Посмотреть сообщение
Я использовал промежуточные таблицы
Аналогично.
__________________
I believe!
Старый 01.09.2008, 10:35   #2  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
Папробуйте вот так:
X++:
while select TableId from custTable
    outer join sum(AmountMST) from custTrans
        group by AccountNum
        where custTrans.AccountNum == custTable.AccountNum
{
}
Таким образом у вас выберутся суммы сгруппированные по коду клиента
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 01.09.2008, 11:57   #3  
koraman is offline
koraman
Участник
 
41 / 11 (1) +
Регистрация: 12.02.2008
Адрес: Казань
Это какая-то мистика! Я, конечно, в аксапте новичок... Она всегда такая непредсказуемая?
Сегодня после поста _scorp_ у меня заработал скрипт, который я выкладывал в начале!
Цель же - немножко посложнее. Мне необходимо вывести для каждого клиента список договоров с указанием суммарного оборота по каждому.
Я создал тестовую формочку с одним единственным гридом, который цепляется к временной табличке, которая перед отображением заполняется своим методом fill().

Итак. Проблема.

Объявление переменных:
X++:
    CustTable custTable;
    ContactPerson contactPerson;
    CustGroup custGroup;
    RContractTable contractTable;
    RContractTypes contractTypes;
    CustTrans custTrans;
    ;
Шаг 1:
X++:
    while select custTable order by AccountNum
        outer join contactPerson where
            custTable.ContactPersonId == contactPerson.ContactPersonId
    {
        this.CustInfo = custTable.AccountNum + ", " + contactPerson.Name;
        this.insert();
    } // end while
Здесь всё нормально. Выбирается, джойнится, отображается.

Шаг 2:
X++:
    while select custTable order by AccountNum
        outer join contactPerson where
            custTable.ContactPersonId == contactPerson.ContactPersonId
        outer join custGroup where
            (custGroup.dataAreaId == contactPerson.dataAreaId || custGroup.dataAreaId != contactPerson.dataAreaId) &&
            custTable.CustGroup == custGroup.CustGroup
    {
        this.CustInfo = custTable.AccountNum + ", " + contactPerson.Name;
        this.CustGroupName = custGroup.Name;
        this.insert();
    } // end while
Добавили ещё один джоин, стали отображать ещё один столбец - и появилась первая проблема! Почему-то у нескольких записей перестало отображаться название группы клиентов CustGroup.Name! Всё вроде бы нормально... В CustTable группа указана, в CustGroup она существует, для многих строк она в гриде отображается, но для некоторых не отображается. Почему?

Шаг 3:
X++:
    while select custTable order by AccountNum
        outer join contactPerson where
            custTable.ContactPersonId == contactPerson.ContactPersonId
        outer join custGroup where
            (custGroup.dataAreaId == contactPerson.dataAreaId || custGroup.dataAreaId != contactPerson.dataAreaId) &&
            custTable.CustGroup == custGroup.CustGroup
        outer join contractTable where
            (contractTable.dataAreaId == custGroup.dataAreaId || contractTable.dataAreaId != custGroup.dataAreaId) &&
            contractTable.RContractPartnerCode == custTable.AccountNum &&
            contractTable.RContractPartnerType == RContractPartnerType::Cust
        outer join contractTypes where
            (contractTypes.dataAreaId == contractTable.dataAreaId || contractTypes.dataAreaId != contractTable.dataAreaId) &&
            contractTypes.ContractCode == contractTable.RContractCode
    {
        this.CustInfo = custTable.AccountNum + ", " + contactPerson.Name;
        this.CustGroupName = custGroup.Name;
        this.ContractRegNo = contractTable.RContractAccount;
        this.ContractNo = contractTable.RContractNumber;
        this.ContractGroupName = contractTypes.ContractCodeName;
        this.insert();
    } // end while
Здесь мы добавили уже два джойна, но осложнений больше нет - всё хорошо и аккуратно... за исключением групп, конечно...

Шаг 4:
X++:
    while select custTable order by AccountNum
        outer join contactPerson where
            custTable.ContactPersonId == contactPerson.ContactPersonId
        outer join custGroup where
            (custGroup.dataAreaId == contactPerson.dataAreaId || custGroup.dataAreaId != contactPerson.dataAreaId) &&
            custTable.CustGroup == custGroup.CustGroup
        outer join contractTable where
            (contractTable.dataAreaId == custGroup.dataAreaId || contractTable.dataAreaId != custGroup.dataAreaId) &&
            contractTable.RContractPartnerCode == custTable.AccountNum &&
            contractTable.RContractPartnerType == RContractPartnerType::Cust
        outer join contractTypes where
            (contractTypes.dataAreaId == contractTable.dataAreaId || contractTypes.dataAreaId != contractTable.dataAreaId) &&
            contractTypes.ContractCode == contractTable.RContractCode
        outer join AccountNum, sum(AmountMST) from custTrans group by AccountNum where
            (custTrans.dataAreaId == contractTypes.dataAreaId || custTrans.dataAreaId != contractTypes.dataAreaId) &&
            custTrans.RContractAccount == contractTable.RContractAccount &&
            custTrans.RContractCode == contractTable.RContractCode
    {
        this.CustInfo = custTable.AccountNum + ", " + contactPerson.Name;
        this.CustGroupName = custGroup.Name;
        this.ContractRegNo = contractTable.RContractAccount;
        this.ContractNo = contractTable.RContractNumber;
        this.ContractGroupName = contractTypes.ContractCodeName;
        this.Amount = custTrans.AmountMST;
        this.insert();
    } // end while
Вот здесь уже всё валится. И по-разному. Вчера это был просто пустой грид, а сегодня уже сообщение типа "Невозможно выбрать запись в CustTable. База данных SQL обнаружила ашипку.".

Хотя и реализовал задачку другим путём, мозги всё равно стремятся сломаться об эти две проблемы...
__________________
I believe!
Старый 01.09.2008, 12:11   #4  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от koraman Посмотреть сообщение
Это какая-то мистика!
Барабашки нет.

Цитата:
Сообщение от koraman Посмотреть сообщение
Шаг 2:
X++:
    while select custTable order by AccountNum
        outer join contactPerson where
            custTable.ContactPersonId == contactPerson.ContactPersonId
        outer join custGroup where
            (custGroup.dataAreaId == contactPerson.dataAreaId || custGroup.dataAreaId != contactPerson.dataAreaId) &&
            custTable.CustGroup == custGroup.CustGroup
    {
        this.CustInfo = custTable.AccountNum + ", " + contactPerson.Name;
        this.CustGroupName = custGroup.Name;
        this.insert();
    } // end while
Очень странное условие в запросе.

Цитата:
Сообщение от koraman Посмотреть сообщение
Добавили ещё один джоин, стали отображать ещё один столбец - и появилась первая проблема! Почему-то у нескольких записей перестало отображаться название группы клиентов CustGroup.Name!
Читайте про outer join на этом форуме.
Аксапта плохо переваривает несколько outer join'ов.

Почему? Потому что разыменование в Аксапте делается совершенно другим способом. Вы привыкли к LEFT JOIN'ам и считаете, что это быстро. Нет, в Аксапте очень много зявязано на кэширование записей (читайте про кэширование в транзакции, вне транзакции, а также кэширование таблиц).

Суть Аксапта-подхода:
1. Естественные коды (коды должны быть такими, что легко читаются и понимаются человеком). В результате потребность в разыменовании резко снижается. См. стандартные формы и отчеты. См. неоднократные обсуждения на этом форуме и здесь http://axapta.mazzy.ru/lib/autonumber/
2. Использовать простые запросы с вложенными простыми и КЭШИРУЕМЫМИ запросами.

Если вам всетаки нужно разыменование, то лучше написать сложенный запрос к CustGroup и при этом убедится что CustGroup кэшируемая таблица
X++:
    while select custTable order by AccountNum
        outer join contactPerson where
            custTable.ContactPersonId == contactPerson.ContactPersonId
    {
        custGroup == custGroup::find(custTable.CustGroup);
    }
Почему так? Потому что внешний запрос будет гораздо проще и поэтому будет быстрее возвращаться. Возвращаемый массив данных будет меньше (что чертовски важно для тонких каналов)

А вот внутренний запрос будет выполняться на SQL только в первый раз за пользовательскую сессию. как правило, результаты будет браться из кэша КЛИЕНТА.

Вывод - не усложняйте запросы. В Аксапте не всегда вложенные запросы плохо.
Детально разберитесь с кэшированием записей.
__________________
полезное на axForum, github, vk, coub.
За это сообщение автора поблагодарили: koraman (1).
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Двойной Outer Join в Query LTA DAX: Программирование 2 21.01.2020 09:28
Несколько outer join в запросе _scorp_ DAX: Программирование 2 11.04.2008 10:56
Данные в Grid из таблиц, связанных по Outer Join cherv DAX: Программирование 2 17.02.2007 01:36
2 и более OUTER JOIN к одному паренту Ronin DAX: Программирование 21 19.12.2005 13:42
outer join для трех таблиц r25 DAX: Программирование 4 29.04.2004 15:42

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

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

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