OLAP.ru   Rambler's Top100
Вы находитесь на страницах старой версии сайта. Перейдите на новую версию OLAP.ru
  
Поиск по сайту
Новости
Основы OLAP
Продукты
Business Objects/ Crystal Decisions
Каталог
OLAP в жизни
Тенденции
Download
Яndex
 
 
 
TopList
 

Введение в OLAP, часть 9. Создание OLAP-клиентов с помощью ADO и ADOMD


Алексей Федоров,
Наталия Елманова, преподаватель УКЦ "Interface Ltd",
КомпьютерПресс #12'2001

 

Применение ADO в OLAP-клиентах
   Чтение метаданных
   Выполнение MDX-запросов
Применение ADO MD в OLAP-клиентах
   Чтение метаданных
   Выполнение MDX-запросов
Применение средств разработки для создания OLAP-клиентов
   Visual Basic for Applications
   Visual Studio .Net
   Delphi и C++Builder
   Заключение

 

Предыдущая часть данной статьи (КомпьютерПресс № 11’2001), а также статья «Введение в MDX», вторую часть которой вы найдете в настоящем номере нашего журнала, посвящены построению запросов к OLAP-кубам с помощью языка MDX (Multidimensional Expressions). Мы убедились, что этот язык позволяет получить из многомерных баз данных любые сведения, содержащиеся в них, и теперь можем приступить к созданию собственных OLAP-клиентов. В качестве средства создания OLAP-кубов мы будем использовать Visual Basic 6. В конце статьи мы также затронем вопрос об использовании других средств разработки.

Cуществует два способа получения данных из OLAP-кубов Microsoft SQL Server 2000 Analysis Services. Первый основан на применении ADO (ActiveX Data Objects) и OLEDB-провайдера для доступа к многомерным данным — Microsoft OLE DB Provider for OLAP Services 8.0. При втором способе используется ADO MD (ADO Multidimensional) — технология, позволяющая обращаться как к метаданным многомерных баз данных, так и к результатам MDX-запросов. Мы начнем с применения ADO, а затем перейдем к ADO MD.

Применение ADO в OLAP-клиентах

С общем случае OLAP-клиент должен уметь не только выполнять MDX-запросы, но и получать сведения о метаданных многомерных баз данных, то есть имена содержащихся в них кубов, их измерений, иерархий, уровней и членов. С точки зрения приложений, не создающих кубы, а только читающих содержащиеся в них данные, члены измерений вполне можно отнести к метаданным, поскольку с точки зрения таких приложений они неизменны. Но, как только мы начинаем создавать приложения, модифицирующие или создающие OLAP-кубы, члены измерения (а в случае некоторых нестандартных типов измерений — и их уровни) к метаданным отнести уже нельзя — их значения определяются в исходном источнике данных, который обычно подвержен изменениям. Впрочем, с помощью ADO и ADO MD кубы обычно не создаются — для этого существуют другие технологии, такие как PivotTabe Services и SQL Decision Support Objects (DSO), о которых будет говориться в последующих частях данной статьи.

Чтение метаданных

Итак, первая задача, которую следует решить, — как получить доступ к метаданным с помощью ADO. Для ее решения в случае реляционных баз данных обычно применяется метод OpenSchema объекта ADO Connection, возвращающий объект ADO Recordset, содержащий сведения о метаданных указанной базы данных. Этот же метод применим и к многомерным базам данных, если обращаться к ним с помощью провайдера Microsoft OLE DB Provider for OLAP Services (или Microsoft OLE DB Provider for OLAP Services 8.0).

Метод OpenSchema имеет три параметра — QueryType, Criteria и SchemaID, из которых обязательным является лишь первый. Среди значений параметра QueryType, имеющих отношение к многомерным базам данных, наибольший интерес представляют значения adSchemaCubes, adSchemaDimensions, adSchemaLevels, adSchemaMembers и adSchemaMeasures, позволяющие получить объект ADO Recordset со сведениями о кубах, измерениях, уровнях, членах измерений и мерах соответственно.

Создадим простейшее приложение для отображения метаданных с помощью Visual Basic 6. Начнем с описания глобальной переменной, которая будет содержать значение QueryType метода OpenSchema:

Public ads As Integer

Далее поместим на главную форму приложения компоненты MSHFlexGrid для отображения результатов, возвращаемых методом OpenSchema, и кнопку для инициирования его выполнения. Поместим на форму также компонент ComboBox, заполним его свойство List значениями Cubes, Dimensions, Levels, Members и Measures и создадим обработчик события Click, связанного с выбором пользователем одного из значений списка:

Private Sub Combo1_Click()
 Select Case Combo1.ListIndex
 Case 0
  ads = adSchemaCubes
 Case 1
  ads = adSchemaDimensions
 Case 2
  ads = adSchemaLevels
 Case 3
  ads = adSchemaMembers
 Case 4
  ads = adSchemaMeasures
 End Select
Command1.Enabled = True
End Sub  

Далее создадим обработчик события Click для кнопки:

Private Sub Command1_Click()
 Dim RS As New ADODB.Recordset
 Dim Cnn As New ADODB.Connection
 Cnn.ConnectionString = "Provider=MSOLAP.2;" & _
  "Persist Security Info=True;User ID=sa;Data Source=MAINDESK;" & _
  "Initial Catalog=NorthWind_OLAP"
 Cnn.Open
 Set RS = CNN.OpenSchema(ads)
 Set MSHFlexGrid1.Recordset = RS
 Set CNN = Nothing
 Set RS = Nothing
End Sub  

В этом обработчике события мы обращаемся к методу OpenSchema объекта Connection c параметром QueryType, соответствующим значению, выбранному из выпадающего списка, и отображаем полученный набор данных в объекте MSHFlexGrid1 рис. 1).



Рис. 1. Получение сведений о метаданных с помощью метода OpenSchema объекта ADO Connection

Таким образом, мы получили доступ к метаданным многомерной базы данных с помощью метода ADO OpenSchema. Нашей следующей задачей будет выполнение MDX-запроса к соответствующим данным. Зная, каковы метаданные, мы вполне можем это сделать.

Выполнение MDX-запросов

Для выполнения MDX-запросов немного модифицируем наше приложение, добавив еще одну кнопку и компонент TextBox для ввода текста MDX-запроса. Создадим обработчик события Click для второй кнопки:

Private Sub Command2_Click()
 Dim RS As New ADODB.Recordset
 Dim Cnn As New ADODB.Connection
 On Error GoTo Err1
 Cnn.ConnectionString = "Provider=MSOLAP.2;" & _
  "Persist Security Info=True;User ID=sa;Data Source=MAINDESK;" & _
  "Initial Catalog=NorthWind_OLAP"
 Cnn.Open
 Set Rs = Cnn.Execute(Text1.Text)
 Set MSHFlexGrid1.Recordset = Rs
 Set Cnn = Nothing
 Set Rs = Nothing
 Exit Sub
 Err1:
  MsgBox ("Неверный запрос")
End Sub  

В этом обработчике события мы инициируем выполнение запроса с помощью метода Execute объекта ADO Connection. Результат его выполнения показан на рис. 2.



Рис. 2. Результат выполнения MDX-запроса с помощью метода Execute объекта ADO Connection

Нужно иметь в виду, что при применении метода Execute объекта ADO Connection результат любого MDX-запроса можно представить в виде двумерного набора данных, даже если этот запрос возвращает набор данных, число измерений в котором более двух. Например, результат запроса:

SELECT measures.members ON columns, product.children ON rows, shipper.children    ON pages FROM sales

представляющий собой трехмерный набор данных, отображается на обычный объект ADO Recordset, содержащий набор последовательных сечений этого трехмерного набора данных рис. 3.



Рис. 3. Результат выполнения MDX-запроса, возвращающего трехмерный набор данных

Таким же образом можно обращаться и к локальным OLAP-кубам, созданным с помощью Microsoft Excel и сохраненным в файлах *.cub. В этом случае свойство ConnectionString объекта Connecton может выглядеть так:

Cnn.ConnectionString =
”Provider=MSOLAP.2;Data Source=C:\Data\Cubes\NW1.cub”

Отметим, что рассмотренный способ создания OLAP-клиентов — не единственный из возможных. Есть еще один способ, довольно часто используемый в коммерческих OLAP-клиентах, — это применение ADO MD. Об этой технологии пойдет речь в следующем разделе.

Применение ADO MD в OLAP-клиентах

ADO MD — это расширение ADO, реализованное в библиотеке msadomd.dll и содержащее объектную модель, позволяющую обращаться как к метаданным многомерных баз данных, так и к результатам MDX-запросов.

Объектная модель ADO MD, представленная на рис. 4, состоит из двух «ветвей» объектов: первая из них используется для доступа к метаданным многомерной базы данных, а вторая — для извлечения данных с помощью запросов к OLAP-кубам.



Рис. 4. Объектная модель ADO MD

Первый из объектов ADO MD для доступа к метаданным, объект Catalog, представляет многомерное хранилище данных, которое может содержать ноль, один или более кубов. Следовательно, одним из свойств объекта Catalog является коллекция CubeDefs. Каждый элемент этой коллекции представляет собой объект CubeDef, описывающий конкретный куб в хранилище. Имя куба — это значение свойства Name соответствующего объекта CubeDef.

Каждый объект CubeDef может содержать коллекцию Dimensions, состоящую из объектов Dimension. Каждый объект Dimension, в свою очередь, представляет конкретное измерение куба, а имя этого измерения содержится в свойстве Name.

Все объекты Dimension заключают в себе коллекцию Hierarchies, которая может содержать один или более объектов Hierarchy. Иерархия же может содержать один или несколько уровней, поэтому объект Hierarchy содержит коллекцию Levels, состоящую из объектов Level. Каждый из уровней иерархии содержит один или более членов, поэтому объект Level содержит коллекцию Members, состоящую из объектов Member.

Чтение метаданных

Используя Visual Basic 6, создадим пример, выводящий сведения о метаданных многомерной базы данных с помощью ADO MD. Для этой цели поместим на форму компонент TreeView и кнопку, создадим обработчик события Click этой кнопки, в котором заполним компонент TreeView сведениями о метаданных (см. листинг 1).

Private Sub Command1_Click()
 Dim Nod, Nod1  As Node, i, j, k, l As Integer
 Dim Cat As New ADOMD.Catalog
 Dim Cnn As New ADODB.Connection
 Cnn.ConnectionString = "Provider=MSOLAP.2;Persist Security Info=True;”_
 +”User ID=sa;Data Source=MAINDESK;Initial Catalog=NorthWind_OLAP"
 Cnn.Open
 Set Cat.ActiveConnection = Cnn
 If Cat.CubeDefs.Count > 0 Then
  Set Nod = TreeView1.Nodes.Add(, , "Catalog", "Catalog")
  For i = 0 To Cat.CubeDefs.Count - 1
   Set Nod1 = TreeView1.Nodes.Add("Catalog", tvwChild, _
   Cat.CubeDefs(i).Name, Cat.CubeDefs(i).Name)
   For j = 0 To Cat.CubeDefs(i).Dimensions.Count - 1
    Set Nod1 = TreeView1.Nodes.Add(Cat.CubeDefs(i).Name, tvwChild, _
    Cat.CubeDefs(i).Dimensions(j).UniqueName, _
    Cat.CubeDefs(i).Dimensions(j).UniqueName)
    For k = 0 To (Cat.CubeDefs(i).Dimensions(j).Hierarchies.Count - 1)
     For l = 0 To _
     (Cat.CubeDefs(i).Dimensions(j).Hierarchies(k).Levels.Count - 1)
      Set Nod1 = _
      TreeView1.Nodes.Add(Cat.CubeDefs(i).Dimensions(j).UniqueName,_
      tvwChild, _
      Cat.CubeDefs(i).Dimensions(j).Hierarchies(k).Levels(l).UniqueName,_
      Cat.CubeDefs(i).Dimensions(j).Hierarchies(k).Levels(l).UniqueName)
     Next l
    Next k
   Next j
  Next i
  Command1.Enabled = False
 End If
End Sub

Результат работы этого приложения показан на рис. 5.



Рис. 5. Приложение для чтения метаданных с помощью ADO MD

Теперь нам осталось решить последнюю задачу — выполнение MDX-запросов с помощью ADO MD.

Выполнение MDX-запросов

В объектной модели ADO MD результат MDX-запроса представлен объектом CellSet. Этот объект позволяет осуществить доступ к объектам Cells, каждый из которых представляет конкретные ячейки в наборе данных, получающемся в результате запроса. Помимо этого объект CellSet содержит коллекцию Axes, состоящую из объектов Axis (число членов этой коллекции равно числу измерений в результирующем наборе данных). Как объект Cell, так и объект Axis обладают коллекцией Positions, состоящей из объектов Position, соответствующих позициям вдоль оси. Объект Position обладает коллекцией Members, члены которой представляют конкретные значения данных на оси.

Добавим в уже созданное приложение возможность выполнять MDX-запросы. Для этого поместим на форму приложения еще одну кнопку, два компонента TextBox и создадим обработчик события Click для этой кнопки (см. листинг 2).

Private Sub Command2_Click()
 Dim Cst As New ADOMD.Cellset
 Dim Cnn As New ADODB.Connection
 Cnn.ConnectionString = "Provider=MSOLAP.2;Persist Security Info=True;”_
 +”User ID=sa;Data Source=MAINDESK;Initial Catalog=NorthWind_OLAP"
 Cnn.Open
 Text2.Text = vbTab & vbTab
 Set cst.ActiveConnection = cnn
 cst.Source = Text1.Text
 On Error GoTo Err
 cst.Open
 For i = 0 To cst.Axes(0).Positions.Count - 1
  Text2.Text = Text2.Text & cst.Axes(0).Positions(i).Members(0).Caption_
  &  vbTab
 Next i
 Text2.Text = Text2.Text & vbCrLf & vbCrLf
 For j = 0 To cst.Axes(1).Positions.Count - 1
  Text2.Text = Text2.Text & cst.Axes(1).Positions(j).Members(0).Caption_
  &  vbTab
  For k = 0 To cst.Axes(0).Positions.Count - 1
   Text2.Text = Text2.Text & vbTab & cst(k, j).FormattedValue
  Next k
  Text2.Text = Text2.Text & vbCrLf
 Next j
Exit Sub
Err:
 MsgBox ("Invalid Query")
End Sub


В данном фрагменте кода мы создаем объект CellSet и используем его метод Open. Если MDX-запрос корректен, то выполняется цикл перебора ячеек объекта CellSet и происходит вывод их содержимого в компонент Text2. Результат работы созданного приложения приведен на рис. 6.



Рис. 6. Приложение для чтения метаданных с помощью ADO MD

Обратите внимание: данный фрагмент кода написан при допущении, что объект Cellset содержит двумерный набор данных. В общем же случае число измерений этого набора данных может превышать указанное значение, и это обстоятельство следует учитывать при создании OLAP-клиентов.

Применение средств разработки для создания OLAP-клиентов

Visual Basic for Applications

Примеры, использующие ADO, почти без изменений можно выполнить в Access VBA, создав форму Access и разместив на ней примерно те же интерфейсные элементы (за исключением TextBox — в Access он предназначен для отображения полей таблиц или запросов, поэтому рекомендуется заменить его на какой-нибудь элемент управления для редактирования текста, например RichEdit Control). Используя позднее связывание, можно решить эту задачу и с помощью других приложений MS Office, например:

Dim cnnConn, rs As Object
Set cnnConn = CreateObject("ADODB.Connection")
Cnn.ConnectionString = "Provider=MSOLAP.2;Persist Security Info=True;”_
 +”User ID=sa;Data Source=MAINDESK;Initial Catalog=NorthWind_OLAP"
Source=e:\old_data\d\whistler\sales.cub"
cnnConn.Open
Set rs = CreateObject("ADODB.Recordset")
Set rs = cnnConn.OpenSchema(ads)  

Что касается примеров, использующих ADO MD, то их воспроизведение с помощью VBA также возможно посредством позднего связывания.

Visual Studio .Net

Поскольку Visual Studio .Net позволяет применять COM и ADO, все описанные выше примеры можно перенести и в это средство разработки, получив в результате проекты Visual Basic .Net, использующие либо ADO, либо ADO MD, равно как и создать их непосредственно с помощью этого средства разработки. Если же мы хотим создать с нуля подобный проект посредством ADO .Net, то можем столкнуться с тем, что метод GetOleDbSchemaTable, являющийся ADO.Net-аналогом метода OpenSchema, в версии Visual Studio .Net Beta 2 не поддерживает многомерные базы данных и что с его помощью можно получить только наименования кубов, но не сведения об изменениях, уровнях, членах и мерах.

Что касается MDX-запросов, их вполне можно выполнять, используя объекты OleDbConnection и OleDbCommand. В дальнейшем мы планируем посвятить ряд статей технологии ADO .Net, где рассмотрим эти объекты более подробно.

Delphi и C++Builder

Пример, аналогичный первому из рассмотренных, можно создать с помощью редакции Enterprise обоих этих средств разработки начиная с версии 5. Для получения сведений о метаданных можно воспользоваться методом OpenSchema компонента TADOConnection:

procedure TForm1.Button1Click(Sender: TObject);
var
 SI : TSchemaInfo;
 I  : Integer;
begin
case ComboBox1.ItemIndex of
  0: SI := siCubes;
  1: SI := siDimensions;
  2: SI := siHierarchies;
  3: SI := siLevels;
  4: SI := siMeasures;
  5: SI := siProperties;
  6: SI := siMembers;
 end;
ADOConnection1.OpenSchema(SI,EmptyParam,   EmptyParam,ADODataSet1);
ADODataSet1.Open;
end;   

Для получения же самих данных можно воспользоваться методом Open компонента TADODataSet:

procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
begin
 If Memo1.Lines.Count > 0 Then
 try
  With ADOQuery1 do
  begin
   Close;
 SQL := Memo1.Lines;
 Open;
  end;
 except
  ShowMessage('Invalid MDX query');
 end;
end;  

Создание OLAP-клиентов с применением ADO MD с помощью этих двух средств разработки также вполне возможно, поскольку оба они поддерживают все способы создания COM-клиентов начиная с версии 3.0. Пример создания такого OLAP-клиента посредством Delphi можно найти в статье «Введение в расширения ADO» (КомпьютерПресс № 10’2000).

Заключение

Итак, мы рассказали о создании OLAP-клиентов с помощью технологий ADO и ADO MD. Рассмотрели задачи чтения метаданных многомерных баз данных, выполнения MDX-запросов и реализовали их на Visual Basic 6.0. Мы также обсудили возможности создания подобных приложений с помощью VBA, Visual Studio .Net, Borland Delphi и Borland C++Builder.

Следующая часть статьи будет посвящена программному созданию OLAP-кубов с помощью Microsoft PivotTable Services.

 Обсудить на форуме   Написать вебмастеру 

© 2001 Interface Ltd