AXForum  
Zurück   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Kennwort vergessen?
Registrieren Forum Rules Hilfe Benutzerliste Heutige Beiträge Suchen

 
 
Themen-Optionen Thema durchsuchen Ansicht
Alt 20.11.2023, 16:28   #1  
Товарищ ♂uatr ist offline
Товарищ ♂uatr
Участник
Benutzerbild von Товарищ ♂uatr
MCBMSS
 
340 / 931 (32) +++++++
Registriert seit: 23.10.2012
Post Объект упрощающий создание расширенных запросов
Всем привет.
Как на проекте, так и на Аксфоруме, встречается код использующий расширенные запросы:
X++:
qbr.value(StrFmt("((%1.%3 != 0) || (%1.%2 != 0))"...
Если с точки зрения из поддержки вопросов особо не возникает, то процесс их написания, как правило, превращается в какое-то испытание.

Во вложении проект содержащий класс QueryBuildRangeCondition. Он упрощает разработку, но обратной стороной является снижение читабельности и быстродействия. Как оформить код, чтобы она не страдала - вопрос открытый. Текущее решение - прототип. Вероятно, это скорее "строитель" корректных запросов.

Реализованные функции...
create - конструктор. Намеренно один и принимает QBDS + FieldName.
toString - результат. Результат ее выполнения необходимо передать в экземпляр QueryBuildRange как value.
value/link- задает оператор сравнения и само значение. В качестве значения можно передать другой QueryBuildRangeCondition.
add/or - добавляют еще один объект QueryBuildRangeCondition через оператор И/ИЛИ.

Пример использования:
X++:
    Query                    q    = new Query();
    QueryBuildDataSource     qbds = q.addDataSource(tableNum(CustTable));
    QueryBuildRange          qbr  = qbds.addRange(fieldNum(CustTable, RecId));
    QueryBuildRangeCondition qbrc = QueryBuildRangeCondition::create(qbds, fieldStr(CustTable, InvoiceAccount))
                                                             .and(
                                                                  QueryBuildRangeCondition::create(qbds, fieldStr(CustTable, RecId)).value(QueryBuildRangeOperator::Equal, 403387)
                                                                  .or(QueryBuildRangeCondition::create(qbds, fieldStr(CustTable, Name)).value(QueryBuildRangeOperator::NonEqual, CustTable::findRecId(403387).Name))
                                                                 )
                                                             .and(QueryBuildRangeCondition::create(qbds, fieldStr(CustTable, RecId)).link(QueryBuildRangeOperator::Equal, qbds, fieldStr(CustTable, RecId)));
    ;
    
    qbds.addRange(fieldNum(CustTable, RecId)).value(qbrc.toString());
Результатом работы toString в данном случае будет:
Code:
((CustTable_1.InvoiceAccount)&&((CustTable_1.RecId=403387)||((CustTable_1.Name!="\"Василий\"")))&&((CustTable_1.RecId=((CustTable_1.RecId)))))
Отдельная благодарность товарищу Logger'у за помощь в создании данного решения.

Geändert von Товарищ ♂uatr (27.11.2023 um 22:23 Uhr)
This post has been rated by: Logger (5), S.Kuskov (10), PavelX (4), Pandasama (3).
Alt 23.11.2023, 07:31   #2  
Pandasama ist offline
Pandasama
Участник
 
473 / 140 (5) +++++
Registriert seit: 11.08.2014
Ort: Барнаул
А более сложные конструкции с различными вложенностями AND и OR и NOT он делать позволяет?
Alt 23.11.2023, 13:52   #3  
Товарищ ♂uatr ist offline
Товарищ ♂uatr
Участник
Benutzerbild von Товарищ ♂uatr
MCBMSS
 
340 / 931 (32) +++++++
Registriert seit: 23.10.2012
Позволяет, вложенному QueryBuildRangeCondition указываете доп. критерии - рекурсия.
Исходный пример выглядел бы примерно так:
X++:
QueryBuildRangeCondition::create(qbds, fieldStr(CustTable, InvoiceAccount))
                         .and(QueryBuildRangeCondition::create(qbds, fieldStr(CustTable, RecId)).value(QueryBuildRangeOperator::Equal, 403387)
                                                       .and(
                                                               ...
                                                           )
                             )
.
NOT - оператор, за это отвечает перечисление QueryBuildRangeOperator. Оно передается как параметр в функции value и link. Больше или равно, просто больше и тд - там же.

Geändert von Товарищ ♂uatr (23.11.2023 um 14:03 Uhr)
Alt 23.11.2023, 14:13   #4  
S.Kuskov ist offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3.450 / 1792 (66) ++++++++
Registriert seit: 28.04.2007
Ort: Калуга
Zitat:
Zitat von Товарищ ♂uatr Beitrag anzeigen
NOT - оператор, за это отвечает перечисление QueryBuildRangeOperator. Оно передается как параметр в функции value и link.
Вы не путаете 'NOT' и 'не равно'?

Можно ли, например, собрать вот такое условие:
Code:
NOT((Table1.Field1 == "aaa") OR (Table2.Field2 == "aaa"))
или нужно обязательно преобразовывать его в
Code:
((Table1.Field1 != "aaa") AND (Table2.Field2 != "aaa"))
?
Alt 23.11.2023, 14:24   #5  
Товарищ ♂uatr ist offline
Товарищ ♂uatr
Участник
Benutzerbild von Товарищ ♂uatr
MCBMSS
 
340 / 931 (32) +++++++
Registriert seit: 23.10.2012
Да, путаю. Не рассматриваю расширенные запросы в рамках чистого TSQL. Спасибо.
Верно пишите, в рамках текущей реализации возможность реверса логики не была заложена и условие нужно будет развернуть.
Добавить можно.
К исправлениям - очевидно, что функция link лишние скобки создает.
Alt 23.11.2023, 15:56   #6  
S.Kuskov ist offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3.450 / 1792 (66) ++++++++
Registriert seit: 28.04.2007
Ort: Калуга
Ещё можно добавить тип сравнения LIKE. Вроде он поддерживается в расширенном синтаксисе начиная с AX2009
This post has been rated by: Logger (1).
Alt 23.11.2023, 19:40   #7  
Logger ist offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
4.001 / 3298 (118) ++++++++++
Registriert seit: 12.10.2004
Ort: Москва
Blog-Einträge: 2
Там еще всякие нюансы были, типа для dimension поля обязательно указывать датасорс итп.
На аксаптапедии было расписано.
Alt 27.11.2023, 22:49   #8  
Товарищ ♂uatr ist offline
Товарищ ♂uatr
Участник
Benutzerbild von Товарищ ♂uatr
MCBMSS
 
340 / 931 (32) +++++++
Registriert seit: 23.10.2012
Привет.
-добавил "реверс" логики блока. Для использования необходимо применять новый конструктор "createNegation". Т.е. добавлена возможность написать:
Code:
NOT((Table1.Field1 == "aaa") OR (Table2.Field2 == "aaa"))
-упразднил избыточные скобки при "линковке" полей источников данных.

Актуальная версия во вложении (предыдущую удалил).

На тему массивов - функционал не расширял, он и так поддерживается:
X++:
QueryBuildRangeCondition::createNegation(qbds, fieldId2Name(tableNum(LedgerTrans), fieldId2ext(fieldNum(LedgerTrans, Dimension), 4))).value(QueryBuildRangeOperator::Equal, 'Что-то');
Code:
!((LedgerTrans_1.Dimension[4]="Что-то"))
Angehängte Dateien
Dateityp: xpo PrivateProject_QueryBuildRangeCondition.xpo (11,9 KB, 624x aufgerufen)

Geändert von Товарищ ♂uatr (27.11.2023 um 23:00 Uhr)
This post has been rated by: ashu (2), Logger (10), Ace of Database (10), Pandasama (3), SRF (2).
Stichworte
extended query, extended query syntax, queryvalue, sysquery

 

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
AX2012: Разработка. Открыть используемый объект sukhanchik DAX: Программирование 0 18.09.2020 14:12
AIF права доступа на создание COM-объекта ex3em DAX: Программирование 1 07.10.2014 19:11
Проверка ВР не заглядывает внутрь расширенных типов-массивов glibs DAX: Программирование 0 26.01.2010 20:16
RLS и программное создание запросов Arahnid DAX: Программирование 3 11.10.2007 18:17
aEremenko: Использование прямых запросов SQL Blog bot DAX Blogs 4 18.07.2007 10:09

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Gehe zu

Рейтинг@Mail.ru
Alle Zeitangaben in WEZ +3. Es ist jetzt 21:03 Uhr.
Powered by vBulletin® Version 3.8.5 (Deutsch)
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.