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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 01.09.2015, 17:16   #1  
syl is offline
syl
Участник
Аватар для syl
 
236 / 21 (1) +++
Регистрация: 10.06.2015
Адрес: Киев
SQL в QueryBuildDataSource
Доброго времени суток!

Пытаюсь разобраться с Query и QueryBuildDataSource в Х++.

Есть SQL запрос такого вида:
PHP код:
select ma.MAINACCOUNTID,DA.NAME
from MainAccount ma
inner join DimensionAttributeValueCombination DAVC on DAVC
.MainAccount MA.RecId
    inner join DimensionHierarchy DH on DH
.RecId=DAVC.AccountStructure
        inner join DimensionHierarchyLevel DHL on DHL
.DimensionHierarchy=DH.RecId
            inner join DimensionAttribute DA on DA
.RecId=DHL.DimensionAttribute
where ma
.MAINACCOUNTID='632.000'
and DA.NAME=N'поставщик' 
Я в принципе записал его на Х++ но не уверен что правильно, и у меня не выходит применить условия:
PHP код:
where ma.MAINACCOUNTID='632.000'
and DA.NAME=N'поставщик' 
если я добавляю строку addRange то код не выполняется.

Вот мой код
X++:
Query q;
    QueryBuildDataSource qbMA;
    QueryBuildDataSource qbDAVC;
    QueryBuildDataSource qbDH;
    QueryBuildDataSource qbDHL;
    QueryBuildDataSource qbDA;
    
    q = new Query();
    
    qbMA = q.addDataSource(tablenum(MainAccount));
    qbMA.relations(false);
    
    qbDAVC = qbMA.addDataSource(tablenum(DimensionAttributeValueCombination));
    qbDAVC.relations(false);
    qbDAVC.addLink(fieldNum(DimensionAttributeValueCombination,MainAccount),fieldNum(MainAccount,RecId));
    qbDAVC.joinMode(JoinMode::InnerJoin);
    
    qbDH = qbDAVC.addDataSource(tablenum(DimensionHierarchy));
    qbDH.relations(false);
    qbDH.addLink(fieldNum(DimensionHierarchy,RecId),fieldNum(DimensionAttributeValueCombination,AccountStructure));
    qbDH.joinMode(JoinMode::InnerJoin);
    
    qbDHL = qbDH.addDataSource(tablenum(DimensionHierarchyLevel));
    qbDHL.relations(false);
    qbDHL.addLink(fieldNum(DimensionHierarchyLevel,DimensionHierarchy),fieldNum(DimensionHierarchy,RecId));
    qbDHL.joinMode(JoinMode::InnerJoin);
    
    qbDA = qbDHL.addDataSource(tablenum(DimensionAttribute));
    qbDA.relations(false);
    qbDA.addLink(fieldNum(DimensionAttribute,RecId),fieldNum(DimensionHierarchyLevel,DimensionAttribute));
    qbDA.joinMode(JoinMode::InnerJoin);
Подскажите правильно ли я его записал, как применить условие, и как его выполнить и узнать результат (меня интересует факт наличия строк удовлетворяющих условия запроса а не сами строки)?
Старый 01.09.2015, 17:49   #2  
Ruff is offline
Ruff
Дмитрий Ерин
Аватар для Ruff
1C
 
475 / 396 (14) ++++++
Регистрация: 18.09.2003
Адрес: Тула
Первое, что бросилось в глаза - в .addLink() параметры перепутаны. Там должно быть сначала parent, потом - this. У Вас вроде наоборот.
Старый 01.09.2015, 17:59   #3  
syl is offline
syl
Участник
Аватар для syl
 
236 / 21 (1) +++
Регистрация: 10.06.2015
Адрес: Киев
А что насчет условий выборки?
Старый 01.09.2015, 20:08   #4  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от syl Посмотреть сообщение
А что насчет условий выборки?
X++:
qbMA.addRange(fieldnum(MainAccount, MainAccountId)).value("632.000");
qbDA.addRange(fieldnum(DimensionAttribute, Name)).value("Поставщик");

В общем случае, для задания значений лучше использовать статический метод SysQuery::value("Поставщик"), который конвертирует любой тип данных в нужную символьную строку. Но здесь это не обязательно. Хотя для порядка можно так

X++:
qbMA.addRange(fieldnum(MainAccount, MainAccountId)).value(SysQuery::value("632.000"));
qbDA.addRange(fieldnum(DimensionAttribute, Name)).value(SysQuery::value("Поставщик"));

Обратите внимание, что AddRange() выполняется на том DataSource к которому относятся поля с условиями.

Цитата:
Сообщение от syl
как его выполнить и узнать результат (меня интересует факт наличия строк удовлетворяющих условия запроса а не сами строки)?
X++:
queryRun = new QueryRun(q);
if (queryRun.next())
{
	// Есть хотя бы одна запись, удовлетворяющая условиям выборки
}
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
За это сообщение автора поблагодарили: syl (1).
Старый 01.09.2015, 21:50   #5  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
X++:
qbMA.addRange(fieldnum(MainAccount, MainAccountId)).value("632.000");
qbDA.addRange(fieldnum(DimensionAttribute, Name)).value("Поставщик");

В общем случае, для задания значений лучше использовать статический метод SysQuery::value("Поставщик"), который конвертирует любой тип данных в нужную символьную строку. Но здесь это не обязательно. Хотя для порядка можно так


А можно и глобальный метод queryValue(anytype), в котором собственно и вызывается sysquery::value удобно просто) хотя и не всегда бывает нужным.
И строковые величины лучше бы метками или же макросами на худой конец, чтобы БП не ругался (переработал я с БП, да )
Старый 02.09.2015, 09:56   #6  
syl is offline
syl
Участник
Аватар для syl
 
236 / 21 (1) +++
Регистрация: 10.06.2015
Адрес: Киев
X++:
qbMA.addRange(fieldnum(MainAccount, MainAccountId)).value("632.000");
qbDA.addRange(fieldnum(DimensionAttribute, Name)).value("Поставщик");
Изначально пробовал такую конструкцию. Код не запускается...

А с этим кодом все ОК )

X++:
qbMA.addRange(fieldnum(MainAccount, MainAccountId)).value(SysQuery::value("632.000"));
qbDA.addRange(fieldnum(DimensionAttribute, Name)).value(SysQuery::value("Поставщик"));
Только в фильтре
X++:
qbMA.addRange(fieldnum(MainAccount, MainAccountId)).value(SysQuery::value("632.000"));
SysQuery::value все же не нужен, с ним запрос принимает не совсем правильную форму и не работает

X++:
SELECT * FROM MainAccount(MainAccount_1) WHERE ((MainAccountId = N'632.000')) ...

Последний раз редактировалось syl; 02.09.2015 в 10:12.
Старый 02.09.2015, 15:58   #7  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Как оказалось, в Ax2012 метод SysQuery::value() выполняет разбор символьной строки и экранирует ряд спец.символов наклонной чертой. В данном случае, экранируется символ точки в значении "632.000"

X++:
SELECT * FROM MainAccount(MainAccount_1) WHERE ((MainAccountId = N'632\.000')) ...
Это значит, что обрамление значений функцией SysQuery::value() - обязательно! Именно с целью экранирования возможных спец.символов, которые могут встречаться в значении. Вероятно, из-за этого у Вас запрос и не запускался. Символ точки в значении "632.000" как-то мешал корректной работе запроса.

PS: Кстати, проверил. Действительно, без экранировки спец.символов через SysQuery::value() соответствующие значения не находятся в таблице. Ошибок не возникает, просто запись не находит...
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...

Последний раз редактировалось Владимир Максимов; 02.09.2015 в 16:18.
За это сообщение автора поблагодарили: AlGol (2).
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
mfp: SQL–More memory and CPU is not always a win Blog bot DAX Blogs 2 24.10.2014 01:19
emeadaxsupport: AX Performance Troubleshooting Checklist Part 1A [Introduction and SQL Configuration] Blog bot DAX Blogs 0 05.09.2014 21:11
emeadaxsupport: How to perform a data center change (change of the physical location) where a SQL server 2008 R 2 cluster installation and MS Dynamics AX 4.0 is involved? Blog bot DAX Blogs 0 21.06.2014 19:19

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

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

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