2013-09-10 3 views
2

Я пишу код клиента для интеграции с ActivePivot. В рамках этого я должен иметь возможность обрабатывать запросы сверления и генерировать соответствующим образом измененный запрос MDX перед отправкой его на сервер.Генерирование запросов свертки MDX

Вот простой пример использования куба изолированной панели ActivePivot. Предположим, что базовый запрос:

SELECT 
{ 
    Hierarchize 
    (
     { 
      [Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember], 
      [Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children 
     } 
    ) 
} ON COLUMNS, 
{ 
    Hierarchize 
    (
     { 
      [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember], 
      [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children 
     } 
    ) 
} ON ROWS 
FROM [EquityDerivativesCube] 

Когда пользователь сверлит вниз на «2М» тенор, я должен был бы произвести:

SELECT 
{ 
    Hierarchize 
    (
     { 
      [Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember], 
      [Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children 
     } 
    ) 
} ON COLUMNS, 
{ 
    Hierarchize 
    (
     { 
      [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember], 
      [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children, 
      [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].[2M].Children 
     } 
    ) 
} ON ROWS 
FROM [EquityDerivativesCube] 

Теперь, для более простых запросов, таких как те выше, я могу только определить точку подстановки в базовом запросе и ввести в нее развернутые пути. Например, базовый запрос для выше будет:

SELECT 
{ 
    Hierarchize 
    (
     { 
      {0} 
     } 
    ) 
} ON COLUMNS, 
{ 
    Hierarchize 
    (
     {1} 
    ) 
} 
ON ROWS FROM [EquityDerivativesCube] 

(очевидно, точки substituion должны их фигурные скобки спаслись, но вы получите идею)

Но с более сложными запросами, такими как с несколькими членами на оси, этот подход быстро ломается. Например, вот запрос с двумя членами по размеру колонки:

SELECT 
Hierarchize(
    Union(
     CrossJoin(
      {[Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember]}, 
      {[Underlyings].[DEFAULT_HIERARCHY].[ALL].[AllMember]} 
     ), 
     Union(
      CrossJoin(
       {[Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember]}, 
       [Underlyings].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children 
      ), 
      Union(
       CrossJoin(
        [Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children, 
        {[Underlyings].[DEFAULT_HIERARCHY].[ALL].[AllMember]} 
       ), 
       CrossJoin(
        [Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children, 
        [Underlyings].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children 
       ) 
      ) 
     ) 
    )) 
ON COLUMNS, 
{Hierarchize(
    {[TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember], 
    [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children})} 
ON ROWS 
FROM [EquityDerivativesCube] 

мне нужно, чтобы быть в состоянии обнаружить запросы бурильных вниз против любых разбуриваемых членов и изменить запрос соответствующим образом, прежде чем повторно представить его.

Так что мне интересно, как это сделать? Моя первоначальная надежда заключалась в том, что MDX сам определил некоторый стандартный механизм для предоставления развернутого запроса на основе некоторых параметров, которые вы передаете ему. Однако я не смог найти ничего подобного.

Таким образом, я боюсь, что мой единственный регресс заключается в том, чтобы самостоятельно проанализировать запрос и ввести динамическую информацию в AST, а затем сгенерировать новый запрос. Может ли кто-нибудь подтвердить это или предложить альтернативный подход?

ответ

4

Вы можете использовать функцию DrilldownMember с флагом RECURSIVE.

Например:

DrilldownMember({ [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember]}, { [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember], [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].[2M]}, RECURSIVE) 

Она возвращает те же члены, чем

{ 
    {[TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember]}, 
    [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children, 
    [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].[2M].Children 
} 
+0

Спасибо - я могу видеть, как это помогает с простыми запросами, но я не вижу, как он может быть применен к более сложным запросам. Я обновил свой вопрос, чтобы включить пример. Не могли бы вы взглянуть и комментировать/обновить свой ответ? –

+0

После экспериментов немного больше, я думаю, что мне нужно сделать, это использовать «CrossJoin» (нет необходимости в «Союзе», который был просто сгенерирован инструментом, который я использовал) с одним вызовом 'DrilldownMember' для каждого члена размерность. Поэтому я бы поддерживал набор элементов для детализации для каждого члена измерения. Когда пользователь упражняется в членах, я добавляю к набору approriate и генерирую запрос соответствующим образом. Когда они развернутся, я удалю из соответствующего набора. Хотелось бы услышать ваши мысли об этом подходе. –

Смежные вопросы