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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 08.10.2004, 14:07   #1  
EreminIgor is offline
EreminIgor
Участник
 
18 / 10 (1) +
Регистрация: 08.10.2004
Адрес: Москва
проблема с query
Помогите разобраться с запросом….

Есть таблицы с такими связями:
Классификатор
|
|-Статья затрат
|
|
|-Объект территории
| \
| Территория
|-Ген. Договор
\
Программа
\
Направление

Суть в том, что нужно сделать inner join по всем таблицам,
чтобы пользователь при вызове prompt() мог ввести что угодно (range) в любой из таблиц
и потом надо выбрать список значений одного из полей таблицы Классификатор.

Вот текст запроса (построен по примерам с axforum, проблема – в qbDS6)


Query query;
QueryRun queryRun;
QueryBuildDataSource qbDS1, qbDS2, qbDS3, qbDS4, qbDS5, qbDS6, qbDS7;
RFORProgrammeClassifierTable rFORProgrammeClassifierTable;
set dims = new set (types::string); // Declare a set of strings
str dimsStr;
int fldId, fldId2;
;

query = new Query();
//Классификатор программ
qbDS1 = query.addDataSource(tableNum(RFORProgrammeClassifierTable));
//Статья затрат
qbDS2 = qbDS1.addDataSource(tableNum(RFORExpenceItemTable));
qbDS2.addLink(fieldNum(RFORProgrammeClassifierTable, RFORExpenceItem), fieldNum(RFORExpenceItemTable, RFORExpenceItem));
qbDS2.joinMode(JoinMode::EXISTSJOIN);
qbDS2.fetchMode(0);
//info(qbDS1.toString());
//Объект
qbDS3 = qbDS1.addDataSource(tableNum(RFORTerritoryItemTable));
qbDS3.addLink(fieldNum(RFORTerritoryItemTable, RFORTerritoryItem), fieldNum(RFORProgrammeClassifierTable, RFORTerritoryItem));
qbDS3.joinMode(JoinMode::EXISTSJOIN);
qbDS3.fetchMode(0);
//info(qbDS1.toString());
//Территория
qbDS5 = qbDS3.addDataSource(tableNum(RFORTerritoryTable));
qbDS5.addLink(fieldNum(RFORTerritoryTable, RFORTerritory), fieldNum(RFORTerritoryItemTable, RFORTerritory));
qbDS5.joinMode(JoinMode::EXISTSJOIN);
qbDS5.fetchMode(0);
//info(qbDS1.toString());
//Ген.договор
qbDS4 = qbDS1.addDataSource(tableNum(RFORGeneralContractTable));
qbDS4.addLink(fieldNum(RFORGeneralContractTable, RFORGeneralContract), fieldNum(RFORProgrammeClassifierTable, RFORGeneralContract));
qbDS4.joinMode(JoinMode::EXISTSJOIN);
qbDS4.fetchMode(0);
//info(qbDS1.toString());
//Программа
qbDS6 = qbDS4.addDataSource(tableNum(RFORProgrammeTable));
fldId = fieldext2id(fieldName2Id(tablenum(RFORProgrammeTable), "RFORProgramme"));
fldId2 = fieldext2id(fieldName2Id(tablenum(RFORGeneralContractTable), "RFORProgramme"));
qbDS6.addLink(fldId, fldId2);
qbDS6.joinMode(JoinMode::EXISTSJOIN);
qbDS6.fetchMode(0);
info(qbDS1.toString());

связь в qbDS6 должна проходить по полям RFORProgramme но проходит по другим –
запрос генерится такой:
SELECT * FROM RFORProgrammeClassifierTable EXISTS JOIN * FROM RFORExpenceItemTable WHERE RFORProgrammeClassifierTable.RFORExpenceItem = RFORExpenceItemTable.RFORExpenceItem EXISTS JOIN * FROM RFORTerritoryItemTable WHERE RFORProgrammeClassifierTable.RFORTerritoryItem = RFORTerritoryItemTable.RFORTerritoryItem EXISTS JOIN * FROM RFORTerritoryTable WHERE RFORTerritoryItemTable.RFORTerritory = RFORTerritoryTable.RFORTerritory EXISTS JOIN * FROM RFORGeneralContractTable WHERE RFORProgrammeClassifierTable.RFORGeneralContract = RFORGeneralContractTable.RFORGeneralContract EXISTS JOIN * FROM RFORProgrammeTable WHERE RFORGeneralContractTable.RFORGeneralContract = RFORProgrammeTable.RFORDirection

То есть поля связываются RFORGeneralContractTable.RFORGeneralContract = RFORProgrammeTable.RFORDirection
А надо RFORGeneralContractTable. RFORProgramme = RFORProgrammeTable. RFORProgramme
Цивилизованный путь через
qbDS6.addLink(fieldNum(RFORGeneralContractTable, RFORProgamme), fieldNum(RFORProgammeTable, RFORProgamme));
приводит к тому же результату, что и через fieldName2Id().

Из-за чего может быть закавыка ?

С уважением, Еремин Игорь
Старый 08.10.2004, 14:38   #2  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
Цитата:
public QueryBuildLink addLink(fieldId _parentField, fieldId _thisField)
Для первой пары Вы правильно указали, а вот все остальные линки не в ту сторону.

Вы, вроде, хотели INNER, а пишите EXISTSJOIN.
Старый 08.10.2004, 15:20   #3  
EreminIgor is offline
EreminIgor
Участник
 
18 / 10 (1) +
Регистрация: 08.10.2004
Адрес: Москва
запрос писался используя материалы статьи
"Древовидная структура источников данных в Query"
http://www.axforum.info/forums/showt...=7889#post7889

Суть в том, что мне не просто нужен запрос который вернет все записи,
а этот query пользователи еще "ограничивают" (добавляют range) если нужно
во время prompt(), и выборка данных должна содержать только тот список значений
таблицы Классификатор, который не противоречит значениям, выбранным пользователями в связанных таблицах (я не знаю как какие поля и какими значениями пользователи захотят ограничить таблицы)

правда, что не в ту сторону - попробовал исправить и
получил также неправильный запрос:

SELECT * FROM RFORProgrammeClassifierTable EXISTS JOIN * FROM RFORExpenceItemTable WHERE RFORProgrammeClassifierTable.RFORExpenceItem = RFORExpenceItemTable.RFORExpenceItem EXISTS JOIN * FROM RFORTerritoryItemTable WHERE RFORProgrammeClassifierTable.RFORTerritoryItem = RFORTerritoryItemTable.RFORTerritoryItem EXISTS JOIN * FROM RFORTerritoryTable WHERE RFORTerritoryItemTable.RFORTerritory = RFORTerritoryTable.RFORTerritory EXISTS JOIN * FROM RFORGeneralContractTable WHERE RFORProgrammeClassifierTable.RFORGeneralContract = RFORGeneralContractTable.RFORGeneralContract AND RFORProgrammeClassifierTable.SupplAgreement = RFORGeneralContractTable.RFORGeneralContract EXISTS JOIN * FROM RFORProgrammeTable

Тут связь ошибочно идет еще и по полю SupplAgreement - аналитике
(AND RFORProgrammeClassifierTable.SupplAgreement = RFORGeneralContractTable.RFORGeneralContract)
и нет связей по полям RFORProgrammeTable
(EXISTS JOIN * FROM RFORProgrammeTable)

исправленный код, создающий query:
Query query;
QueryRun queryRun;
QueryBuildDataSource qbDS1, qbDS2, qbDS3, qbDS4, qbDS5, qbDS6, qbDS7;
RFORProgrammeClassifierTable rFORProgrammeClassifierTable;
set dims = new set (types::string); // Declare a set of strings
str dimsStr;
int fldId, fldId2;
;

query = new Query();
//Классификатор программ
qbDS1 = query.addDataSource(tableNum(RFORProgrammeClassifierTable));
//Статья затрат
qbDS2 = qbDS1.addDataSource(tableNum(RFORExpenceItemTable));
qbDS2.addLink(fieldNum(RFORProgrammeClassifierTable, RFORExpenceItem), fieldNum(RFORExpenceItemTable, RFORExpenceItem));
qbDS2.joinMode(JoinMode::EXISTSJOIN);
qbDS2.fetchMode(0);
//info(qbDS1.toString());
//Объект
qbDS3 = qbDS1.addDataSource(tableNum(RFORTerritoryItemTable));
qbDS3.addLink(fieldNum(RFORProgrammeClassifierTable, RFORTerritoryItem), fieldNum(RFORTerritoryItemTable, RFORTerritoryItem));
qbDS3.joinMode(JoinMode::EXISTSJOIN);
qbDS3.fetchMode(0);
//info(qbDS1.toString());
//Территория
qbDS5 = qbDS3.addDataSource(tableNum(RFORTerritoryTable));
qbDS5.addLink(fieldNum(RFORTerritoryItemTable, RFORTerritory), fieldNum(RFORTerritoryTable, RFORTerritory));
qbDS5.joinMode(JoinMode::EXISTSJOIN);
qbDS5.fetchMode(0);
//info(qbDS1.toString());
//Ген.договор
qbDS4 = qbDS1.addDataSource(tableNum(RFORGeneralContractTable));
qbDS4.addLink(fieldNum(RFORProgrammeClassifierTable, RFORGeneralContract), fieldNum(RFORGeneralContractTable, RFORGeneralContract));
qbDS4.joinMode(JoinMode::EXISTSJOIN);
qbDS4.fetchMode(0);
//info(qbDS1.toString());
//Программа
qbDS6 = qbDS4.addDataSource(tableNum(RFORProgrammeTable));
qbDS4.addLink(fieldNum(RFORGeneralContractTable, RFORProgramme), fieldNum(RFORProgrammeTable, RFORProgramme));
qbDS6.joinMode(JoinMode::EXISTSJOIN);
qbDS6.fetchMode(0);
info(qbDS1.toString());
Старый 08.10.2004, 15:37   #4  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Re: проблема с query
Цитата:
Изначально опубликовано EreminIgor
Вот текст запроса (построен по примерам с axforum, проблема – в qbDS6)
Игорь, настоятельный совет - не программируйте.

Создайте нужный вам Query в AOT.
Там его создавать намного легче.

В коде напишите ОДНУ строчку
PHP код:
Query q = new Query(querystr(myQueryInAOT)); 
Все ваш query готов к употреблению.
Мучайте его также, как и созданный в коде.

Но! Созданный в АОТ query, у вас будет гарантированно правильным.
Да и проверять его намного легче.
За это сообщение автора поблагодарили: d_alexe (1).
Старый 08.10.2004, 16:10   #5  
EreminIgor is offline
EreminIgor
Участник
 
18 / 10 (1) +
Регистрация: 08.10.2004
Адрес: Москва
собственно, я с этого и начинал...
еще раз проверил - создал query аналогичный своему программному
ошибки логические остаются - query работает неправильно:
то есть если пользователь выбирает направление или программу
(то есть самые дальные таблицы в иерархии), и заводит по ней range,
то запрос работает неправильно - выдаются все доступные строки таблицы "Классификатор"
в трассировке запрос роазбирается на два запроса:
первый с таблицами Классификатор, Объект, Территория и Статья затрат.
Второй с таблицами направление и программа.

Соответственно если фильтр пользователя приходится на программу
то первый запрос select * from RFORProgrammeClassifierTable ....
уже выдает все значения строк таблицы классификатор и программой они не ограничиваются !
Старый 08.10.2004, 16:36   #6  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
Некоторые общие рекомендации, которые я стараюсь выполнять при работе с Query
1. Минимизировать количество ветвлений
2. Использовать только inner join
3. Не объединять более 5 таблиц

Что делать в вашем случаи не знаю.
Можно после диалога с юзером разбивать запрос на 2 (главный, по которому строится отчет и ограничитель, который выполняется в цикле), но это МНОГО кодинга.
Наверное, имеет смысл пойти на упрощение задачи.
Старый 08.10.2004, 17:49   #7  
macklakov is offline
macklakov
NavAx
Аватар для macklakov
 
2,262 / 980 (37) +++++++
Регистрация: 03.04.2002
2 EreminIgor: вряд ли кто тебе ответит на этот вопрос. Хотя бы потому, что в такой куче кода, возиться не охота. Чудес явно нет, если аккуратно перебрать работать будет. Для начала, заставь работать запрос в аксаптовском sql, чтоб знать, что логика правильная. А потом, по частям, делай Query и на каждом шагу проверяй. Тогда багу не укрыться!
P.S. Осознать такой запрос целиком не возможно физиологически даже в момент озарения, т.к. 7 сущностей, и еще связи...
__________________
Isn't it nice when things just work?
Старый 11.10.2004, 16:57   #8  
EreminIgor is offline
EreminIgor
Участник
 
18 / 10 (1) +
Регистрация: 08.10.2004
Адрес: Москва
Решил-таки...всем кто участвовал в обсуждении большое спасибо за ответы

Упростил задачу - немного денормализовал таблицу "Генеральный договор" - храню там еще и поле "Направление", таким образом 2 join с таблицами "программа" и "направление" стали ненужными.
Запрос правильно заработал (программно), только когда стал выглядель так:

Классификатор
|
|-Статья затрат
|
|-Ген. Договор (включая поля Программа, Направление)
|
|-Объект территории
\
Территория

(то есть подчиненная относительно таблицы "Классификатор" таблица,
имеющая в свою очередь подчиненную таблицу, находится в "конце" запроса)
Видимо, запрос с двумя "ветвями" подчинения выполняется некорректно всегда.

Привожу исходный код:

static void TestQuery(Args _args)
{
Query query;
QueryRun queryRun;
QueryBuildDataSource qbDS1, qbDS2, qbDS3, qbDS4, qbDS5;
RFORProgrammeClassifierTable rFORProgrammeClassifierTable;
set dims = new set (types::string); // Declare a set of strings
str dimsStr;
int fldId, fldId2;
;

query = new Query();
//Классификатор программ
qbDS1 = query.addDataSource(tableNum(RFORProgrammeClassifierTable));
qbDS1.addRange(fieldNum(RFORProgrammeClassifierTable, RFORProgrammeClassifier));
//Ген.договор (в т.ч. программа и направление)
qbDS4 = qbDS1.addDataSource(tableNum(RFORGeneralContractTable));
qbDS4.addLink(fieldNum(RFORProgrammeClassifierTable, RFORGeneralContract), fieldNum(RFORGeneralContractTable, RFORGeneralContract));
qbDS4.joinMode(JoinMode::EXISTSJOIN);
qbDS4.fetchMode(0);
qbDS4.addRange(fieldNum(RFORGeneralContractTable, RFORProgramme));
qbDS4.addRange(fieldNum(RFORGeneralContractTable, RFORDirection));
qbDS4.addRange(fieldNum(RFORGeneralContractTable, RFORGeneralContract));
//info(qbDS1.toString());
//Статья затрат
qbDS2 = qbDS1.addDataSource(tableNum(RFORExpenceItemTable));
qbDS2.addLink(fieldNum(RFORExpenceItemTable, RFORExpenceItem), fieldNum(RFORProgrammeClassifierTable, RFORExpenceItem));
qbDS2.joinMode(JoinMode::EXISTSJOIN);
qbDS2.fetchMode(0);
qbDS2.addRange(fieldNum(RFORExpenceItemTable, RFORExpenceItem));
//info(qbDS1.toString());
//Объект
qbDS3 = qbDS1.addDataSource(tableNum(RFORTerritoryItemTable));
qbDS3.addLink(fieldNum(RFORTerritoryItemTable, RFORTerritoryItem), fieldNum(RFORProgrammeClassifierTable, RFORTerritoryItem));
qbDS3.joinMode(JoinMode::EXISTSJOIN);
qbDS3.fetchMode(0);
qbDS3.addRange(fieldNum(RFORTerritoryItemTable, RFORTerritoryItem));
//info(qbDS1.toString());
//Территория
qbDS5 = qbDS3.addDataSource(tableNum(RFORTerritoryTable));
qbDS5.addLink(fieldNum(RFORTerritoryItemTable, RFORTerritory), fieldNum(RFORTerritoryTable, RFORTerritory));
qbDS5.joinMode(JoinMode::EXISTSJOIN);
qbDS5.fetchMode(0);
qbDS5.addRange(fieldNum(RFORTerritoryTable, RFORTerritory));
//info(qbDS1.toString());


queryRun = new QueryRun(query);
if (queryRun.prompt())
{
while (queryRun.next())
{
rFORProgrammeClassifierTable = queryRun.get(tablenum(RFORProgrammeClassifierTable));
dims.add(rFORProgrammeClassifierTable.SupplAgreement[3]);
}
}

box::info(dims.toString());
}
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Dynamics AX: QueryRun and Query Objects - Binding operation failed to allocate buffer space Blog bot DAX Blogs 0 03.04.2009 08:05
palleagermark: Sample union query from AX 2009 Blog bot DAX Blogs 0 11.07.2008 20:05
Проблема с Query в AOT radya DAX: Программирование 7 17.10.2007 17:28
Dynamics AX Geek: Using query() Blog bot DAX Blogs 0 28.10.2006 16:40
Проблема с составлением Query axaLearner DAX: Программирование 10 01.12.2005 15:00

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

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

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