Введение в SQL Server Analysis Services для разработчика. Параметризованные MDX-запросыИсточник: blogstechnet
Странно, но иногда на семинарах обнаруживается, что народ искренне полагает, будто в 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>
или наоборот? Не знаю, Моше виднее.
Рис.1
К сожалению, редактор XMLA в SSMS отображает результат запроса в его исконном виде XML и не позволяет его отобразить в виде наглядного набора ячеек, как это умеет делать редактор MDX Query:
Рис.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 с точностью до форматирования.
Рис.3
В данном примере по-прежнему используется доступ к Analysis Services по HTTP. Если дело происходит в пределах одного домена, то, как отмечалось в одном из предыдущих постов, можно заменить строку соединения на "Data Source= 192.168.0.29". Тогда бы SOAP шел непосредственно по ТСР.
Возникает вопрос, неужели верхнеуровневость ADOMD.NET по сравнению с SOAP не позволит выполнить из нее полноценный XMLA просто как он есть? Без того, чтобы предварительно сепарировать его на команду, свойства, параметры и т.д. и рассовывать это хозяйство по разным объектам ADOMD.NET. Смотрите следующую серию. |