SQL Server 2000 Analysis Services 支持许多用于 OLAP 的新的结构功能、安全功能和管理功能选项 — 包括链接的多维数据集、计算的单元、命名集和分布式分区的多维数据集。Analysis Services 还包含一些用于开发人员的新功能,例如,通过钻取浏览明细数据行的功能,以及允许用户通过使用操作来作用于多维数据集内的单元的功能。在这两种情况下,这些特性所提供的功能在过去即使能够实现,那么在实现时也是非常困难的。Russ Whitney 在 Mastering OLAP 专栏的 "Analysis Services Drillthrough"(2000 年 6 月发表,InstantDoc ID 85301)一文和 "Analysis Services Actions"(2000 年 7 月发表,InstantDoc ID 8758)一文中,讨论了如何将这些功能用于 ADO MD。在本文中,我将说明开发人员如何通过添加钻取支持和实现操作,来利用用于 Web 应用的 Analysis Services。
实现钻取
在 Microsoft 发布了 SQL Server 7.0 OLAP 服务后,用户使用最频繁的功能就是检索用于计算特定单元的值的基础数据的功能。举例来说,如果您需要知道某个单元包括哪些客户或哪些产品,该功能就显得非常有用。就其本质而言,OLAP 在实现聚合事实数据表的行的功能(这是它的关键优势)的同时也对明细数据行进行了抽象化,并因此使明细数据行的查找变得很困难。在发布 Analysis Services 之前,面临这种挑战的开发人员不得不在多维数据集成员和关系之间实现元数据映射层(它包含星型架构或雪花型架构)。访问单元时,代码既要读取多维数据集成员信息,又要读取应用于查询的任何筛选器。然后,代码必须生成 SQL 查询,以便联接关系中的多个表、执行查询并返回结果集。编写可正确地以这种方式访问单元的代码并不轻松。但有了 Analysis Services 以后,您根本就无需编写或维护这种代码。
Analysis Services 包含了用来实现钻取的代码;第 38 页的server/art/OLAPforDevelopersFigure_01.gif" target="_blank">图 1 显示了 Analysis Services 如何完成钻取的高级视图。客户端应用执行从本地透视表服务传递到 OLAP 的 MDX 语句。请记住,透视表服务是 OLE DB 提供,它提供缓存、本地多维数据表处理以及到 Analysis (OLAP) 的连接。然后,OLAP 使用多维数据集中的配置选项和安全设置来创建 SQL 语句,并将它发送到保存明细数据的关系。SQL 语句再通过 OLAP 和透视表服务将返回的 OLE DB 行集发回到客户端应用。通常,客户端通过 ADO Recordset 对象访问数据。
要实现钻取功能,您必须既要执行管理任务,又要执行应用特定的任务。从管理员的角度来说,第一个任务是启用多维数据集的钻取功能。管理员控制多维数据集钻取功能的启用是至关重要的,因为单元常常包含来自数千行甚至数百万行的数据,因此让所有用户不受限制地查询此数据可能导致瓶颈。要对多维数据集启用钻取功能,请启动“多维数据集编辑器”,然后依次选择“工具”和“钻取选项”。在得到的“多维数据集钻取选项”对话框中,只需选中“启用钻取”复选框,如server/art/OLAPforDevelopersFigure_02.gif" target="_blank">图 2 所示。Analysis Services 支持常规多维数据集、虚拟多维数据集或链接多维数据集的钻取,但 Analysis Services 不允许您对某类单元使用钻取,这类单元具有基于计算的成员单元或自定义成员公式的值。
请注意,在图 2 所示的情况中,您必须启用钻取,并且要使列的列表包含来自架构中的事实数据表和维数表的所有列。在此示例中,多维数据集的名称是 Enrollment,利用该多维数据集,可以针对 Quilogy 技术培训课程中的学生注册情况生成报表。根据您在该对话框中所选择的列,Analysis Services 会在查询基础数据时联接适当的表。图 2 中的对话框还包含“筛选”选项卡,该选项卡可包含用于限制结果集中的行数的 WHERE 子句。但是,由钻取动态生成的 WHERE 子句除外。
除了以多维数据集级别启用钻取,您还可以对包含一个以上分区的多维数据集中的每个分区的选项进行修改。您可以通过在“磁盘分区向导”(要访问“磁盘分区向导”,请右击某个分区,然后从上下文菜单中选择“编辑”)中单击“高级设置”按钮和“钻取选项”来访问与图 2 中的对话框相类似的对话框。您可以在显示的“分区钻取选项”对话框中,更改从该分区创建钻取数据时所要使用的列和筛选器。可对各个分区设置钻取选项的功能意味着,如果您对聚合一个以上分区中数据的单元执行钻取操作,每个分区将返回其自己的结果集,而且那些结果集中的列可以互不相同。应用开发人员需要意识到这一行为,这样他们就可以根据需要来显示结果。管理员的下一个任务是配置钻取安全设置,为此,您需要使用“多维数据集角色管理器”对话框,针对您要向其授予访问权限的角色单击“钻取”设置。每个角色都有一个名为“允许钻取”的安全设置,您可以选择该设置,以便允许角色执行使用钻取操作的查询。
用于开发人员的钻取
当您启用钻取并配置安全设置之后,即可为应用实现钻取。为了说明实现钻取所需的步骤,我向 Active Server Pages (ASP) 页面添加了钻取功能,该页面基于随 Analysis Services 提供的 ASPADOComplex. 页面。此页面执行一个显示 Quilogy 地点、在每个地点登记的学生天数和收入金额的查询(当然数据都是虚构的),如server/art/OLAPforDevelopersFigure_03.gif" target="_blank">图 3 所示。
在基于 Web 的应用中,在 UI 中提供钻取支持的最自然的方式是将超级链接放在单元上,以便允许用户单击该链接来显示明细数据。请注意,图 3 中的每个单元都包含一个超级链接。要生成超级链接,可以修改下面的语句,以便包括或更换可输出单元值的 ASPADOComplex. 代码:
Response.Write " <ahref=Drillthrough.?colName=" & _colName(k) & "&rowName="& rowName(j) & _"&cube=Enrollment&Where=" &Server.URLEncode(strWhere) & ">" _& cst(k, j).FormattedValue & "</a>"
请注意,超级链接调用 Drillthrough. 页面,通过查询串向该页面传递当前列和行成员名称、多维数据集以及 MDX 语句为生成单元集而所使用的任何 WHERE 子句。ASPADOComplex. 页面中的代码在 ASP 页面中创建表行和列标头时,将行名和列名作为填充的数组进行存储。下面的代码从 MDX 语句提取 WHERE 子句,然后将值发送到 Drillthrough. 页面,mag02/html/OLAPforDevelopersListing_01.txt" target="_blank">清单 1显示了该页面。
intPos = Instr(Session("MDXQuery"),"WHERE")If IntPos > 0 Then strWhere = Mid(Session("MDXQuery"),intPos)
Drillthrough. 创建一个包括 DRILLTHROUGH 关键字的 MDX 语句,来命令 OLAP 创建和执行一个查询,以返回所请求的明细数据。您可以将 DRILLTHROUGH 关键字放在 MDX 语句的前面,该语句可以包含 MAXROWS 和 FIRSTROWSET 参数,以便限制返回客户端的行数,而且如果多维数据集包含多个分区,该语句还可以确定首先返回哪个分区的数据。OLAP 在应用多维数据集或分区的筛选器后应用 MAXROWS。请注意,在清单 1 中的标注 A 中,该页面将行数限制为返回 5000 行。要创建 MDX 语句,该页面随后追加到参数在查询串(列名、行名、多维数据集和 WHERE 子句)中传递、并通过 ASP Request 对象访问的 strSource 变量。例如,如果您单击 Cincinnati 的 Days 列,该页面将创建以下 MDX 语句:
DRILLTHROUGH MAXROWS 5000SELECT {[Measures].[Days]} ON COLUMNS,{[Location].[All Location].[N].[Cincinnati]}ON ROWSFROM Enrollment
为了执行 MDX 语句,调用 Connection 对象的 Execute 方法。此示例将 ADOMD.Catalog 对象的 ActiveConnection 属性设置为和目录名称,它们是用户的会话在调用 Execute 之前就已经包含的名称。在 Web 应用中,Execute 方法的返回值是 ADO 记录集,而不是像 ADO MD 中那样的单元集。因为 Web 应用中的钻取可以返回多个记录集,所以您应该编写循环中的代码,以检索结果,并将结果格式化为 HTML 表,如清单 1 中的标注 B 所示。
记录集对象的 NextRecordset 方法返回为其他分区创建的记录集,或者,如果不存在其他记录集,则什么也不返回。如果您确信其他分区的记录集包含相同的列,可以使用 ASP 代码合并结果。不过,在此示例中,PrintTable 过程只将一个附加的 HTML 表放在返回用户的页面上。server/art/OLAPforDevelopersFigure_04.gif" target="_blank">图 4(第 40 页)显示了得到的明细数据。
实现操作
开发人员可以利用的第二个 Analysis Services 功能是操作。与钻取一样,操作是连接多维数据集与附加数据的纽带;与钻取不同的是,操作非常灵活,Analysis Services 并不使它们只限于将单元链接到生成它的关系数据。您可以从名称看出来,操作允许用户作用于分析,方法是为他们提供用来以多维数据集、维数、级别、成员或单元级别处理数据的选项。基本上,利用操作,用户可以启动一个解决问题或提供有关多维数据集中的数据的更多信息的过程。例如,假设 Quilogy 的销售人员和市场营销人员可以访问 Enrollment 多维数据集。当它们通过 ASP 应用浏览多维数据集数据时,一个可能的操作是单击超级链接,以便查看某个课程的教学大纲。教学大纲可能会使他们更好地理解课程的内容,以及它是如何关联到多维数据集中明显的销售趋势上的。您可以通过以下方法实现此示例:以多维数据集级别创建 URL 操作来提供课程信息。mag02/html/olapfordevelopers_table1." target="_blank">表 1显示了 Analysis Services 中可用的操作类型以及它们的一些可能的用法。与钻取一样,实现操作需要两个步骤。首先,从管理员的角度来看,您必须创建操作;然后,从开发人员的角度来看,您可以修改应用,使应用能够识别操作。
要创建操作,可使用多维数据集编辑器。右击多维数据集的 Actions 夹来调用 Action Wizard。该向导将带领您完成几个步骤,第一个步骤是确定操作的目标(即整个多维数据集、某个特定级别、维数、单个单元或命名集)。如果您选择一个维数或某个特定级别,则您还需要确定维数或级别,并指出当用户单击标题或实际维数或级别时操作是否可用。在该示例中,Quilogy Education 多维数据集包含一个名为 Course 的维数,它包含 Vendor Name、Product Name 和 CourseNum 级别。CourseNum 标识 Quilogy 提供的课程。例如,官方课程 (Microsoft Official Curriculum, MOC) 的课程编号是 2072。选择级别后,该向导会显示您要从中进行选择的操作类型下拉列表。在此示例中,您希望创建一个 URL 操作。
下一个向导屏幕允许您定义返回客户端应用的操作语法,该语法随后用于启动该操作。在此示例中,您需要将操作语法格式化为 URL。此向导屏幕包含一个调用 MDX 生成器的按钮,这样您就可以将数据从多维数据集合并到操作语法中。因为在用户单击某个课程编号时会启动此操作,所以,得到的 URL 必须结合课程编号,以便建立到课程教学大纲的链接。因此,您需要选择维数,并使用 CurrentMember 函数和 Name 属性返回单击的课程编号。
"http://www.quilogy.com/courses/"+ [Course].CurrentMember.Name +".htm"
然后,您可以为操作命名,操作将出现在 Actions 夹中。
用于开发人员的操作
将操作添加到多维数据集后,开发人员方面有两个主要任务:首先,您必须创建一个接口,这样,当操作可用时用户就可以识别,其次,您必须让用户调用操作。对于此示例,我修改了前面的 ASPADOComplex. 页面,以便使它能够识别操作。首先,ASP 页面必须查询多维数据集,以确定某个特定成员是否有与其相关联的操作。您可以使用 ADO Connection 对象的 OpenSchema 方法来执行此功能。此方法接受一个确定要返回的行集类型的常量,以及一个指定用来创建行集的限制的数组。Analysis Services 通过将常量 adSchemaActions 添加到 OLE DB 规范,然后将它作为第一个参数传递到 OpenSchema 来扩展该规范。返回的行集(称为 MDSCHEMA_ACTIONS 行集)包含每个操作的一行,并包括mag02/html/olapfordevelopers_table2." target="_blank">表 2 显示的列。OpenSchema 的第二个参数是一个数组,它定义了一组施加在表 2 中的列上的限制。表 2 还显示限制数组的顺序,以及该参数是否可选。
接下来,您需要一个 UI 提示,这样,当操作可用时,用户就可以识别。为了创建该提示,我向 ASP 页面添加了端的 DisplayURLAction 过程和相关常量,如第 42 页的mag02/html/OLAPforDevelopersListing_02.txt" target="_blank">清单 2 所示。请注意,该过程首先执行 OpenSchema,如清单 2 中的标注 A 所示,以便使用 Array 函数来传递 adSchemaActions 常量和限制集。在此示例中,数组指定 Enrollment 多维数据集(第三个参数);URL 操作类型(第五个参数);要查询操作的成员,该成员传递到 DisplayURLAction 过程(第六个参数);操作的范围(第七个参数)— 在此示例中,操作是成员级别的。请注意,您可以使用空串 (" ") 来传递可选参数。
如果 OpenSchema 查找操作,则 DisplayURLAction 过程会依靠动态 HTML (DHTML) 来创建映像标记,如清单 2 中的标注 B 所示。映像标记显示一个可见的 UI 提示(一个映像),以及一个针对为成员定义的每个 URL 操作包含一行的表(最初是隐藏的),如清单 2 中的标注 C 所示。此外,清单 2 中的标注 B 显示,映像标记的 onClick 属性被设置为调用一个名为 ShowActions 的客户端脚本过程。第 42 页的mag02/html/OLAPforDevelopersListing_03." target="_blank">清单 3 显示的 ShowActions 被传递给该表的元素 ID,以便它可以在 block 和 none 之间切换显示属性。于是,当用户单击映像时,ShowActions 根据设置显示或隐藏该成员的操作列表。表的类属性被设置为 clsActionMenu,该属性将游标类型设置为 hand,以便提供一个用户可以通过单击来获取操作菜单的可见提示,如清单 2 中的标注 C 所示。表中的每一行均包含一列,该列显示从行集合返回的 URL 操作,如清单 2 中的标注 C 所示。
该表的 CONTENT 列包含管理员定义的、当多维数据集生成操作时动态创建的 URL。ACTION_NAME 列包含操作的名称,在此示例中名称是 Syllabus。该列的 onClick 属性在清单 2 中的标注 C 中进行设置,以便运行客户端 InvokeURLAction 过程。当用户单击操作时,InvokeURLAction 过程使用 Document Object Model (DOM) 窗口对象的 Open 方法在一个单独的窗口中打开 URL。
剩下的唯一任务是,将调用定位到 DisplayURLAction。ASPADOComplex. 页面包含重复 MDX 查询在单元集中生成的轴的循环。当行标头和列标头的标题输出到 ASPADOComplex. 页面时,下面的语句调用具有成员的 UniqueName 的 DisplayURLAction 过程:
Call DisplayURLAction(cst.Axes(1).Positions(j).Members(h).UniqueName)
如果 DisplayURLAction 找到了操作,则该过程会将它们的映像添加到 HTML 流,并将该流发送到客户端。得到的页面显示 MDX 查询的结果,该查询将 Course- Num 成员与为课程 2072 激活的操作一起使用,如server/art/OLAPforDevelopersFigure_05.gif" target="_blank">图 5 所示。请注意,每个课程编号正右侧的图标是 URL 操作对此成员来说为存在的可见提示。
新的维数
通过将钻取支持和操作添加到 OLAP 客户端应用,您可以为用户提供信息的全新维度。Analysis Services 减少了开发人员以前为 OLAP 服务提供这些选项所需的大量工作。让我们来看看您怎样才能将钻取和操作集成到 Web 应用。如果您是要求 Microsoft 添加这些功能的许多开发人员中的一个,我就不必再重复这个建议了。