Введение в SQL Server Analysis Services для разработчика. Параметризованные MDX-запросы

Странно, но иногда на семинарах обнаруживается, что народ искренне полагает, будто в MDX-запрос в отличие от SQL нельзя передать параметры. Я думаю, это заблуждение происходит скорее всего оттого, что в SQL Server Management Studio в редакторе Analysis Services MDX Query нет возможности задать параметризованный запрос. Синтаксис MDX поддерживает параметры в запросе, а почему их не удосужились приспособить в SSMS - вопрос к тем, кто ее писал. Параметры можно передать, написав классический XMLA. Если вместо Analysis Services MDX Query открыть в SSMS Analysis Services XMLA Query и изобразить что-нибудь навроде

<Execute xmlns="urn:schemas-microsoft-com:xml-analysis">

  <Command>

    <Statement>

      select [Measures].members on 0,

      Filter(Customer.[Customer Geography].Country.members,

      Customer.[Customer Geography].CurrentMember.Name = @CountryName) on 1

      from [Adventure Works]

    </Statement>

  </Command>

  <Properties>

    <PropertyList>

      <Catalog>Adventure Works DW 2008R2</Catalog>

    </PropertyList>

  </Properties>

  <Parameters>

    <Parameter>

      <Name>CountryName</Name>

      <Value>'United Kingdom'</Value>

    </Parameter>

  </Parameters>

</Execute>

Скрипт 1

можно видеть, что параметризованные запросы прекрасно работают (см. Рис.1). Еще возникает недоумение, что бы в синтаксисе XMLA было не сделать однотипными элементы <Properties> и <Parameters>? Например, вместо

<Properties>

    <PropertyList>

      <Catalog>Adventure Works DW 2008R2</Catalog>

    </PropertyList>

  </Properties>

сделать, как у параметров:

<Properties>

    <Property>

      <Name> Catalog</Name>

      <Value> Adventure Works DW 2008R2</Value>     

    </Property>

  </Properties>

или наоборот? Не знаю, Моше виднее.

image

Рис.1

К сожалению, редактор XMLA в SSMS отображает результат запроса в его исконном виде XML и не позволяет его отобразить в виде наглядного набора ячеек, как это умеет делать редактор MDX Query:

image

Рис.2

Ровно так же параметризованный запрос можно выполнить из приложения. Программно заслать в AS произвольный XMLA-запрос можно, например, средствами SOAP, как рассматривалось в одном из предыдущих постов.  В ADOMD.NET, как мы помним, в AdomdCommand можно засунуть только начинку элемента Command. Элементы Properties и Parameters в XMLA-запросе находятся на одном уровне с элементом Command и в его InnerXml не попадают. Для их передачи используются коллекции Properties и Parameters класса AdomdCommand:

using System.Data;

using System.IO;

using System.Xml;

using System.Diagnostics;

using Microsoft.AnalysisServices.AdomdClient;

class Program

{

    static void Main(string[] args)

    {

        AdomdConnection cnn = new AdomdConnection(@"Data Source=http://192.168.0.29/msolap/msmdpump.dll; User ID=192.168.0.29\\Administrator;Password=cth%tyflf");

        cnn.Open();

        AdomdCommand cmd = new AdomdCommand(

          @"select [Measures].members on 0,

    Filter(Customer.[Customer Geography].Country.members,

           Customer.[Customer Geography].CurrentMember.Name = @CountryName) on 1

    from [Adventure Works]", cnn);

        cmd.Properties.Add("Catalog", "Adventure Works DW 2008R2");

        cmd.Parameters.Add(new AdomdParameter("CountryName", "United Kingdom"));

        CellSet res = cmd.ExecuteCellSet();

        for (int i = 0; i < res.Axes[0].Positions.Count; i++)

        {

            Debug.WriteLine("");

            for (int j = 0; j < res.Axes[1].Positions.Count; j++)

                Debug.Write(res.Cells[i, j].FormattedValue);

        }

        cnn.Close();

    }

}

Скрипт 2

В данном случае название базы перешло из элемента Catalog родительского элемента PropertyList родительского элемента Properties

<Properties>

    <PropertyList>

      <Catalog>Adventure Works DW 2008R2</Catalog>

    </PropertyList>

  </Properties>

(Скрипт 1) в член коллекции cmd.Properties["Catalog"] - см.Скрипт 2, а параметр запроса - из элемента  

<Parameters>

    <Parameter>

      <Name>CountryName</Name>

      <Value>'United Kingdom'</Value>

    </Parameter>

  </Parameters>

(Скрипт 1) в член коллекции cmd.Parameters["CountryName"]. Можно посмотреть на результат и убедиться, что он совпадает с рис.2 с точностью до форматирования.

image

Рис.3

В данном примере по-прежнему используется доступ к Analysis Services по HTTP. Если дело происходит в пределах одного домена, то, как отмечалось в одном из предыдущих постов, можно заменить строку соединения на "Data Source= 192.168.0.29". Тогда бы SOAP шел непосредственно по ТСР.

Возникает вопрос, неужели верхнеуровневость ADOMD.NET по сравнению с SOAP не позволит выполнить из нее полноценный XMLA просто как он есть? Без того, чтобы предварительно сепарировать его на команду, свойства, параметры и т.д. и рассовывать это хозяйство по разным объектам ADOMD.NET. Смотрите следующую серию.


Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=23771