




已阅读5页,还剩62页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第5章 设计数据访问在几乎任何情况下,报表都是以某种数据源为基础。所以,在设计报表时的第一件事就是创建一个连接,定义必要的查询来获取报表数据。本章将讨论报表设计必需的第一 步如何使用数据。尽管设计数据源和查询时一般很简单直接,但仍有大量选项需要考虑。虽然SQL Server报表服务是和SQL Server数据库产品一起提供的,但是它同样可以将其他数据库产品作为数据源。本章讨论了如下主题: 创建独立和共享的数据源。 设计查询和数据集。 在数据库中使用参数来筛选数据。 在报表服务器上使用参数来筛选数据。 使用分析服务和MDX查询生成器。 从其他数据源获取数据。每个报表至少有一个数据源(也有极少数用于特殊目的的报表不使用任何数据)。最简单的报表有一个单一数据集提供的数据源。数据源定义了一个文本字符串的连接,把它存储在报表定义文件中或者一个分离的、几个报表共享的数据源文件中。这个连接信息可以包括安全认证。数据集定义了一个查询表达式或者一个用于查询数据库中对象的引用。数据集也包括在报表定义中。下图5-1描述了数据如何流向报表。数据源提供了连接到数据库的能力,数据集包括了一个为报表产生数据的查询表达式。图 5-1更多复杂的报表需要多个数据集来为报表中的不同数据范围或者数据项提供数据或为参数值选择列表赋值。数据集可以基于同一数据源的查询表达式,如图5-2所示。多个数据集可以从多个数据源获得数据。这个模型可以使报表能够从本地数据库获得参数值而从中央数据存储中获得报表数据。在某些情况下,数据区域、子报表和不同的报表项可以通过相关数据集的多个数据源来获得数据,如图5-3所示。图 5-2图 5-3正如所看到的,几乎可以用任何方式组合数据源和数据集。数据源实际上可以是任何数据库产品或者任何通过标准连接库或者驱动查询的数据源。报表服务使用.NET数据提供程序来利用数据,它包括了对SQL Server、Oracle以及所有OLE DB提供程序的支持。这些几乎包括了所有支持ODBC访问或者ISAM驱动的数据库产品。报表服务中的数据集通常是只读的,所以不需要指定光标类型或者锁定选项。5.1 关系数据报表在前一章中,我们简单查看了怎样使用查询生成器。现在可以进一步看看如何创建查询和怎样为报表提供数据。在这里,理解报表的基本构建块是重要的。讨论将从这些基础开始。读者将会遇到几个短的练习,从中体会它是如何工作的。这里假设读者已经使用过了Visual Studio 2005,并且已经用报表向导创建过报表。如果读者和我一样是一个.NET的程序员,可能见过“数据集”这个词,并想,“我知道数据集是什么,而且我一直在通过.NET数据访问程序代码来使用它,所以我在报表服务的数据访问上已经领先了一步。”如果读者不是一个.NET程序开发人员,比那些需要重新学习一遍这个词的程序员也领先了一步。附带说一下,如果不是.NET应用程序开发人员,读者根本不需要考虑这个问题。为什么术语“数据集”会代表两种完全不同的事物?我们很久以前已经用完了英语中的所有新词。每个人都知道根据环境判断,我们需要再利用。所以这就是我们所做的回收词汇和短语。这个词就是一个经典的例子。在报表服务中,已经有了报表定义中查询的概念,就是为报表输出提供数据值;我们在Microsoft的好朋友决定称之为“数据集”。如果读者在.NET Framework中通过编程方式访问过数据库,应该知道数据集是一个存放缓冲数据的对象,它在内存中是一个XML定义的结构体。虽然这里提到的两个“数据集”都是用来处理数据、查询、结果集以及绑定报表中显示的数据,但它们是两个完全不同的概念。现在,因为我们已经明确了这些概念,看看这句话:如果要在程序代码中定义一个数据源扩展,可以使用ADO.NET数据集来作为生成报表的一个数据集。在几乎任何情况下,报表都是以某种数据源为基础。所以,在设计报表时的第一件事就是创建一个连接,定义必要的查询来获取报表数据。本章将讨论报表设计必需的第一 步如何使用数据。尽管设计数据源和查询时一般很简单直接,但仍有大量选项需要考虑。虽然SQL Server报表服务是和SQL Server数据库产品一起提供的,但是它同样可以将其他数据库产品作为数据源。本章讨论了如下主题: 创建独立和共享的数据源。 设计查询和数据集。 在数据库中使用参数来筛选数据。 在报表服务器上使用参数来筛选数据。 使用分析服务和MDX查询生成器。 从其他数据源获取数据。每个报表至少有一个数据源(也有极少数用于特殊目的的报表不使用任何数据)。最简单的报表有一个单一数据集提供的数据源。数据源定义了一个文本字符串的连接,把它存储在报表定义文件中或者一个分离的、几个报表共享的数据源文件中。这个连接信息可以包括安全认证。数据集定义了一个查询表达式或者一个用于查询数据库中对象的引用。数据集也包括在报表定义中。下图5-1描述了数据如何流向报表。数据源提供了连接到数据库的能力,数据集包括了一个为报表产生数据的查询表达式。图 5-1更多复杂的报表需要多个数据集来为报表中的不同数据范围或者数据项提供数据或为参数值选择列表赋值。数据集可以基于同一数据源的查询表达式,如图5-2所示。多个数据集可以从多个数据源获得数据。这个模型可以使报表能够从本地数据库获得参数值而从中央数据存储中获得报表数据。在某些情况下,数据区域、子报表和不同的报表项可以通过相关数据集的多个数据源来获得数据,如图5-3所示。图 5-2图 5-3正如所看到的,几乎可以用任何方式组合数据源和数据集。数据源实际上可以是任何数据库产品或者任何通过标准连接库或者驱动查询的数据源。报表服务使用.NET数据提供程序来利用数据,它包括了对SQL Server、Oracle以及所有OLE DB提供程序的支持。这些几乎包括了所有支持ODBC访问或者ISAM驱动的数据库产品。报表服务中的数据集通常是只读的,所以不需要指定光标类型或者锁定选项。5.1 关系数据报表在前一章中,我们简单查看了怎样使用查询生成器。现在可以进一步看看如何创建查询和怎样为报表提供数据。在这里,理解报表的基本构建块是重要的。讨论将从这些基础开始。读者将会遇到几个短的练习,从中体会它是如何工作的。这里假设读者已经使用过了Visual Studio 2005,并且已经用报表向导创建过报表。如果读者和我一样是一个.NET的程序员,可能见过“数据集”这个词,并想,“我知道数据集是什么,而且我一直在通过.NET数据访问程序代码来使用它,所以我在报表服务的数据访问上已经领先了一步。”如果读者不是一个.NET程序开发人员,比那些需要重新学习一遍这个词的程序员也领先了一步。附带说一下,如果不是.NET应用程序开发人员,读者根本不需要考虑这个问题。为什么术语“数据集”会代表两种完全不同的事物?我们很久以前已经用完了英语中的所有新词。每个人都知道根据环境判断,我们需要再利用。所以这就是我们所做的回收词汇和短语。这个词就是一个经典的例子。在报表服务中,已经有了报表定义中查询的概念,就是为报表输出提供数据值;我们在Microsoft的好朋友决定称之为“数据集”。如果读者在.NET Framework中通过编程方式访问过数据库,应该知道数据集是一个存放缓冲数据的对象,它在内存中是一个XML定义的结构体。虽然这里提到的两个“数据集”都是用来处理数据、查询、结果集以及绑定报表中显示的数据,但它们是两个完全不同的概念。现在,因为我们已经明确了这些概念,看看这句话:如果要在程序代码中定义一个数据源扩展,可以使用ADO.NET数据集来作为生成报表的一个数据集。5.3 筛选技术从数据源中获取报表数据时,基于用户的选择标准考虑最有效的方式筛选报表数据是很重要的。很多数据库含有大量数据。因此,只获取报表所需要的恰当数据量常常是重要的。有时,一个报表只用于查看一个有限范围值的数据,其他时候用户指定不同的标准,引起报表显示一个变化范围的相关值。在可能取值的范围很小的情况下,只获取相关联数据更具有意义。但是,如果用户在一个会话中指定不同的标准使得数据源需要多次重新查询这证明是低速的和资源利用效率低下。在图5-7中,提供给数据源的参数引起数据筛选,并且只返回报表单一显示的数据中。该数据集代表了在客户端的数据库服务器(报表服务器)的结果集。如图5-7所示,经过筛选后,只是少量数据存在数据库中。图 5-7通过传递数据库对象级别的筛选标准参数,网络传输量可以大大降低,报表显示也会更加高效。但是,如果用户提供多组不同的参数值,在一段时间内返回了同一报表的几个版本,那么数据库将重复查询,也许会导致很长的等待时间和相同数据多次在网络中传输。如图5-8所示,因为没有进行数据筛选,数据库服务器返回了大量的数据。然后报表服务器通过使用报表参数对数据进行了筛选。在用户的一次会话中,对即将执行的查询来说,如果其必需的所有数据都能从一个结果集内获取,那么这将一次执行的巨大的网络传输量。但是这会减少后续报表显示时间。参数选择可以应用于报表级别的数据而不只是数据源。因为所有的数据都被缓存(在内存中保留),报表将会显示更快。这个技术可以减少总体的网络流量和显示时间。当然,我们不想从数据源获取不必要的信息,所以根据特定的报表需求,上述两种方法的结合也许是比较恰当的解决方案。例如,作为一个区域销售经理,想获得自己负责区域下每个地区的销售总计,他得先取回某时间段内所有地区的销售数据。对于每个地区报表来说,这一数据都是经过简单筛选后发到上个级别的地区。图 5-85.3.1 参数概念虽然我认为这不是过于复杂,但是开始时我发现整个参数问题有一些困惑。直到我有机会在查询和报表表达式方面做一些带有参数的创造性的工作。为了减轻读者的苦恼(希望可以缩短读者学习历程),我将解释简单查询和报表中的参数是如何定义的以及如何在更加复杂的报表中使用(和定义)参数。报表设计中会声明两种(也许会是三种,取决于查询技术)不同类型的参数:数据集参数和报表参数。数据集参数源于数据库对象,比如存储过程和用户定义函数。如图5-9所示,可能会接触到参数的设计过程分为三个不同的层。采用SQL Server作为数据源时,SQL语法通过在参数名前面加一个符号作为前缀来定义参数。在存储过程中,这些参数先进行定义然后用于程序主体,与使用即席查询一样。报表设计器生成相应的报表参数。图5-9的第三部分显示了打开的带有两个导出的参数Report Parameter对话框。如果采用图形化查询生成器或者一般查询设计器来写一个典型的Transact-SQL语句,报表设计器将解析数据集参数和数据库对象参数,自动建立相应的报表参数。数据集参数映射到Dataset Properties对话框中的报表参数,如图5-10所示。该对话框可通过单击省略号()按钮访问,按钮在报表设计器的Data选项卡中数据集下拉列表旁边。图 5-9图 5-10对于基本查询,报表设计器将填充对话框并匹配参数。但是,如果是复杂或者不常见的数据集查询,则需要手动配置数据集和报表参数。在很多事件中都执行参数解析,包括单击Refresh按钮时、选取另一个数据集时或者离开报表设计器Data选项卡时。进行特殊查询时需要人工介入,建议对报表最终的工作版本保存一个备份副本,复制查询文本到记事本,以备需要时恢复。5.3.2 用查询参数筛选数据参数常被用来在数据源筛选数据。无论数据是否在报表中进行筛选,对于大多数报表处理工作来说,至少在数据库中筛选数据是一个基本的方法。如果读者曾在SQL Server中建立过参数化存储过程,那么已经熟悉这一模式。这个技术应用到存储过程和查询表达式上,使用类似的语法。让我们由一个简单的即席查询表达式开始,然后继续创建一个存储过程。查询参数以符号开始,必须遵守对Transact-SQL标识符的命名约定标准。命名不能含有空格或某些标点符号,不能以数字开头;简单起见,只使用字母。存储过程中,使用参数前,必须事先对参数作声明。在即席查询中,需要时,可对参数命名做简单修饰。在SQL语句的WHERE部分内,用参数代表变量值,如下所示:SELECT * FROM Products WHERE ProductID = ProductID这种情况下,参数名与相应的字段名一致,但是这种情况不是必需的。如果是利用查询生成器创建一个更为复杂的查询,则要在生成器网格的Criteria列内指定参数。如图5-11所示。图 5-11这个例子中,满足ListPrice列的值小于或等于ListPriceMax参数指定的值条件的行,都要作为记录返回。5.3.3 报表参数除了来自数据集参数的报表参数外,还要增加一些个人的报表参数。这些报表参数(没有对应的查询参数)可以加入进来支持附加的报表功能,比如隐藏和显示报表段、页码和动态格式化。下面的例子演示了一些简单的报表参数,用于在报表上动态设置值。随后,我们将 在几个实际报表特性中运用此方法。这个例子要演示两个非常简单的报表参数,用于教学目的。不使用向导,创建一个新报表。可以通过以下步骤完成:在Solution Explorer的右键菜单中选择Add,然后选择Add New Item;在Add New Item对话框内的报表项模板中,选择Report。不要为新创建的报表指定数据集,切换到报表设计器的Layout视图。报表参数通过Report Parameters对话框进行添加。选择Properties窗口的Report项,单击ReportParameters属性旁边的省略号()按钮。如图5-12所示,ReportTitle参数是一个字符串值,其默认值是Report Title,TextColor参数与其类似,默认值为Blue。图 5-12在报表设计器内,从Toolbox窗口拖曳出两个文本框放置到报表主体。通常情况下,为项提供一个恰当的名称是个好主意(特别是它们为同一表达式所引用时),但是在这个简单例子中,没有必要这样做。为这两个文本框设置属性:每个文本框的Value属性和第二个文本框的Color属性,依照下列说明。设计器在文本框中显示值属性,但是在标准属性窗口或者自定义文本框Properties对话框(右击文本框,选择Properties)中改变这些属性值是个好主意。第一个文本框将从ReportTitle参数获得它的值。设置它的Value属性=Parameters! ReportTitle.Value,设置第二个文本框的Value属性=“This Text is ” & Parameters! TextColor.Value。选择第二个文本框,设置它的Color属性=Parameters! TextColor.Value(参见图5-13)。图 5-13如果想装饰一下的话,还可以改变FontSize和FontWeight属性。我给报表加了条线。现在,单击Preview选项卡,注意发生的变化。预览窗口的标题显示了ReportTitle和TextColor两个参数的默认值,这两个值显示于报表中。尝试用标题内的参数字段来改变ReportTitle和Color,然后单击View Report按钮,刷新报表预览。第一个文本框应该显示了输入ReportTitle参数的文本,第二个文本框应不只显示指定的色彩名称,文本也应呈现为该颜色,如图5-14所示。图 5-14正如所看到的,这是一种向报表内添加用于表达式的值的有效途径。我们将扩展这一方法,提供筛选和动态格式化。5.3.4 基于查询的参数无论是来自于查询参数,还是在报表中显式创建,报表参数广泛用于报表中。它常使报表用户从一系列项中做出选择来提供一个参数值。参数项可以由一个静态列表或者一个数据驱动的查询填充。参数值可以从通过一个数据集从一个数据源中选择,该数据集在报表设计器内建立,与用于报表自身的任一数据集相似。一个报表包含任何数量的数据集,其中一些提供参数值,其余的提供报表内项的数据。利用示例Northwind数据库举一个简单的例子。报表由一个数据集驱动,该数据集从Products表选择记录,Products表中,CategoryID与用户指定参数值相匹配,CategoryID参数值则基于另一个数据集,这个数据集从Categories表中选择CategoryID和CategoryName列。在报表管理器中,用户简单地从一个下拉菜单内选择一个分类名,然后报表只展示出于所选类相匹配的产品。在即将到来的过程练习中将创建不同的参数,不但驱动报表,而且为多重相关参数筛选值。5.3.5 层叠参数刚刚我所描述的行为我们称之为层叠参数。这是报表管理器中的一个特性,允许因一个参数值的选择而生成另一个由相关值组成的参数列表。有时候要基于另一个参数选择筛选一个参数列表。在前文关于产品类别和产品的例子中,可以说对Products表的选取是为了提供另一个参数值,这个参数值用来生成一个所选产品的销售记录报表。在这种情况下,就需要先选择类别。这会提供一个筛选的产品列表,此列表将用于选择一个指定产品。然后产品选择被用来显示销售报表。我将列举另一个关于AdventureWorks2000数据库的例子。我提高一些难度,创建三个参数来驱动一个相当简单的过程例子。练习的输出结果是一个显示某个指定地点的店铺报表。读者将被提示选择一个国家。选定国家后,就列出了相关的州或省。从中选择一个城市为自己所用。选择列表中的一项,将驱动报表数据一列所选城市的店铺。这个过程要求读者或者完成了前一章的步骤,或者已经了解如何创建一个报表项目和共享数据源。开始前,先添加一个新报表到Visual Studio报表项目种。在Solution Explorer中右击Reports,选择Add,然后选择Add New Item。从模板列表中选择Report,并为之命名。我的取名叫做Cascading_Parameters。我知道,这个名字不是很有想象力,但是它是很准确。此时,应该看到报表设计器的Data选项卡。下拉Dataset列表,选择New Dataset。出现的对话框如图5-15所示。为新的数据集输入名称Country_List。为AdventureWorks数据库(在前面章节中已完成创建)选择或建立一个共享数据源,然后单击OK按钮,移到查询生成器窗口。不使用全部查询生成器过程,只将SQL语句键入SQL面板。将光标放置在第三个面板内,就在SQL窗体下方(在两个网格之间)键入以下代码:注意,回车和大部分空格都是随意的。唯一的关键空格在单词ORDER和BY之 间。其他所有单词之间都应该有一到两个空格。这个查询不使用任何参数,因为它不会被筛选。下拉Dataset列表,选择New Dataset,重复执行创建一个新数据集的操作步骤,新数据集命名为StateProvince_List。该数据集的SQL表达式也要输入查询生成器窗口:如果使用查询生成器创建该表达式,则要另外插入几个语句。这同样不是必需的,而且空格和回车不是特别重要。这个表达式包括一个参数,CountryRegionCode,此参数由前面数据集的一个选定行获取其参数值。将为报表而创建一个相应的参数,名为CoutryRegionCode。下拉数据集列表,创建第三个数据集,叫做City_List。与上一个数据集一样,这个数据集也包括一个由选定州或省获取参数值的参数。为该数据集输入下面SQL语句:因为没有城市专有表,所以可以利用Address表在City列的分组来帮助去除重复。通过使用StateProvinceID参数,该查询将返回一个选定的州或省的城市列表。最后,需要为报表自身建立数据集。对此,SQL将变得复杂。由于AdventureWorks2000的规范化设计,从一个城市到一家店铺要经过几个有必要的报表值的表。让我们为它使用查询生成器。如果愿意,可以跳过下面查询生成器的步骤,直接在SQL面板输入SQL语句。再添加一个数据集,命名为Stores_By_City。使用工具栏转换到图形化查询设计器,单击Add Table工具栏按钮(或右击窗体顶部,选择Add Table),按照如图5-16所示的顺序添加图内所示的表:Address、CustomerAddress、Customer、Store、StateProvince和CountryRegion。图 5-16连接将会由查询生成器自动添加。在StateProvince和CountryRegion表之间会添加一个多余的连接。要去掉这个连接的话,单击此行,然后按delete键。在第二个面板内,按照看到的顺序选择表列。或者使用列和表网格内的下拉列表,或者在第一个面板里面的表格内检验它们。因为Store和CountryRegion表格都包含有叫做Name的列,可以用别名使这些列名更具描述性。在网格内输入别名,如图5-17所示。图 5-17最后,输入查询参数StateProvinceID和City,如图5-17所示。数据集应当已经完成。对它进行检验,将此SQL语句与查询生成器中的SQL语句相比较:现在看一下配置参数。转换到Layout选项卡,从Properties窗口下拉列表中选择Report项。单击ReportParameters属性旁边的省略号按钮。打开Report Parameters对话框,如图5-18所示。图 5-18参数CountryCode将从Country_List数据集获取其参数值。与大部分典型的查找表类似,键值不是一个用户易读取的数值,而是用来通过外键关系指示相关表的所选国家。在Parameter列表框中选择这个参数,然后输入Country作为提示。这是用户查看报表时,在参数下拉列表后将会看到的标题。确保所有复选框都未选中,提示用户必须选择从下拉列表中选择一个值。参数下拉列表将在Name列显示值,并在CountryRegionCode列返回相应的值。相应地设置Label字段和Value字段的属性。最后,通过选择最后的单选按钮指示无默认值,一切都完成后,单击OK。我们将为另两个参数重复此过程。利用下面的Report Parameters对话框,设置这些 属性。StateProvinceID参数的配置如图5-19所示。图 5-19这个参数的属性设置与前文相似。这回使用StateProvince_List数据集作为下拉列表数据源。读者应该还记得这个数据集含有一个叫做CountryRegionCode的查询参数。报表引擎足够智能,能将先前参数数据集的Value字段和这个数据集的相应参数连接起来。一个参数选择将为下一个参数筛选列表,只要这些参数按照它们依赖性的顺序排列。最后的一个参数,City,其配置如图5-20所示。图 5-20与前面的参数非常相似,City参数从City_List数据集获取其值的列表,它含有一个查询参数,与参数StateProvinceID的值字段选择相关。报表易于设计。这里强调要调整文本框项大小,以便能够在报表设计器的视图中阅读它们的值属性(参见图5-21)。图 5-21报表主体底部的宽长方形是一个列表项。先把它从Toolbox拖到报表主体中,再将它的DataSetName属性设置为Stores_By_City。Toolbox位置在设计器窗口左侧,是一个扳手和锤子的图标。创建数据绑定文本框最容易的方法是将字段从字段列表(位于左侧Toolbox附近)中拖出来。打开字段列表,下拉顶部列表,选择Stores_By_City数据集。现在,将CustomerID和Name的字段拖到事先建好的列表项上。从Toolbox拖出两个文本框到列表上,改变Value属性为CustomerID和Store,如 图5-22所示。Stores By Location、Country、State/Province和City文本框也全都未绑定,当作静态标签使用。图 5-22拖放CountryName,StateProvinceCode和City字段到报表主体顶部相应的文本框右侧。注意,这3个项的值含有一些额外信息。当一个项不在列表、网格或其他重复数据行的容器项中时,聚合函数(像这里使用的First( )函数功能)是必要的。因为报表定义多于一个数据集,数据集名需要传递给First函数的第二个参数。通过这些适当的设置,读者应该能够预览报表、看到结果。转换到Preview选项卡,在下拉菜单中选择一个国家。如图5-22所示,从列表中选择United States,激活State/Province参数列表。下拉列表,看到列表中只有United States的州。选择AZ for Arizona,激活City参数列表。下拉City列表,选择Phoenix,单击View Report按钮,如图5-23所示。图 5-23可见,为了尽可能地轻松使用参数,报表管理器提供了大量内置功能。即使是在Microsoft Access中,获得此类行为都需要编写一些代码。多选参数SQL Server Reporting Services 2005的这些新特性将参数化的报表带到一个新层次。任一基于选择列表的参数,无论是静态的或是数据驱动的,都可以是一个多选参数。建立多选参数非常容易。在查询中使用它们,只需多花费一点精力,但是总之,使用这个特性建立一个报表并不困难。如果用分析服务,MDX查询生成器自始至终创建多选参数和所有的支持查询脚本。如果使用SQL就不会这样。下面的例子引领读者经历用多选参数创建SQL报表的步骤。我将从后往前为读者展示该过程的机制。这个简单的报表将展示所选产品的子类的产品列表。在为主数据集创建SQL查询之前,我想先为展示一下参数如何设定。图5-24所示为ProductSubCategory参数的Report Parameters对话框。为了启用特性,简单地选上Multi-value属性框。图 5-24这个操作做了两件事情。首先改变了返回到ProductSubCategories查询参数的值。现在,我将展示为参数提供值的查询。下面是一个叫做Product_SubCategory_List的数据集的SQL查询:可见,参数值由ProductSubCategoryID列提供,一个Int型特征关键值。但是,当选择了多个值而且这个参数传送回主数据集时,这个参数值转换为一个包括逗号界定的键列表的字符串。这恰好是应用Transact-SQL IN( )函数的正确形式。在单一选择查询中,WHERE子句看起来类似下面格式:WHERE ProductSubCategoryID = ProductSubCategoryID但是,在启用的多选查询中,参数传递给IN( )函数,如下:WHERE ProductSubCategoryID IN(ProductSubCategories)这是完整的查询:当部署的报表在报表管理器中运行时,参数下拉列表由一个下拉复选框列表所替代。如图5-25所示。图 5-25一个有趣的事实是在HTML中没有类似下拉复选框列表这样的控件。那么,这怎么可能?这个特性是通过使用非常有创造力的JavaScript编程来实现的。最后,所显示报表在图5-26中显示。注意折叠的参数列表显示了一个逗号定界的子类别名称值列表而不是传递给查询的参数值。这是因为列表使用参数的Label属性而不是Value属性来显示所选成员。这里有一个有趣的挑战:我说过查询参数返回一个所选值的逗号界定的列表,和IN( )这个SQL函数一起使用。我将显示一个类似的列表,也许在报表标题有用户友好的Label属性来从参数列表中记录所选项。但是,当我在表达式中引用参数时(使用或者Parameters!ProductSubCategories.Value或者Parameters!ProductSubCategories.Label)返回错误。我可以检查映射到数据集中的查询参数,正如所料,它设置成为Parameters!ProductSub- Categories.Value。这怎么可能?图 5-26在选中Report Parameters对话框中的框来启用多值功能时,参数值(和Label)属性作为数组而不是单一值来管理。如果使用表达式生成器来引用参数,会看到只引用了多选列表中的头一个值,使用索引0:Parameters!ProductSubCategories.Label(0)为什么0是第一个元素而不是1?这是编程规则。在Visual Basic中,当数组和集合枚举时,第一个索引是0。这意味着如果有3个元素,索引将是从0到3。现在回到主数据集的查询。在这个场景背后,数组被解析,所选值被转换为用逗号界定的列表用于查询。要在报表中以相似的方式使用这些值需要一些编程。下面的Visual Basic函数可以用来转换参数Label属性数组为一个字符串值,以在报表标题中使用它,如图5-27所示。图 5-275.3.6 使用存储过程查询数据源最好的方式高度取决于需求。参见前面关于筛选技术的讨论,参数处理(在数据库服务器、客户端上或者两个都有)影响性能、效率和报表解决方案的灵活性。在数据库服务器上处理参数几乎总是更有效率,而在客户端处理参数将赋予处理更大范围记录和查询选项而不需要每次显示报表时返回数据库的灵活性。使用参数化的存储过程通常是筛选数据最为有效的途径,因为它只返回匹配标准的数据。存储过程在服务器端编译为处理器指令。在任何类型的查询在处理时,SQL Server创建了一个执行计划,它定义了服务器用于获取数据的特定指令。在存储过程的情况下,执行计划在第一次执行时准备,然后缓存到数据库服务器中。在后面的执行中,结果将会更快地返回,因为一些工作已经做过了。SQL Server的存储过程可以在三个不同的地方创建:SQL企业管理器、SQL查询分析器或者Visual Studio集成的查询生成器。在下一个练习中,创建一个存储过程用于柱状报表。通过Server Explorer执行来获得到数据库服务器的连接然后管理服务器上的对象。在Visual Studio中,可以看到Server Explorer(默认位于设计器的左边)。如果不在那里,可以使用View菜单来启用这个窗口。要管理数据库中的对象,必须首先定义一个数据库服务器的连接。要做到这点,右击Data Connection项,从菜单中选择Add Connection。Add Connection对话框和用来定义报表数据源的非常类似。保存连接之后,用+号展开它,然后右击Stored Procedures。从上下文菜单中,选择Add New Stored Procedure,如图5-28所示。这个动作会打开新设计器窗口来创建一个新的存储过程。图5-29的文本演示了一个简单的存储过程的基本结构。图 5-29替换过程名和参数,增加一个Transact-SQL语句来完成过程。注意代码窗口左边的行数是Visual Studio编辑器中的可选特性,不是存储过程文本的一部分。如果没有看见它,不必担心。标出过程名(dbo.StoredProcedure1)并用spGetStoresByLocation来替换它。标出所有块中的绿色文本包括/*和*/,删除它,用下面的替代:StateProvinceCode Char(2),City nVarChar(30)空格和缩进不重要。标出并删除文本/* SET NOCOUNT ON*/并在这个位置右击。从上下文菜单中选择Insert SQL。在查询生成器中,在第三个面板下面输入下列代码(在第二个和第四个面板之间的网格):再说一下,使用空格和缩进(还有回车)不是必需的,但是对提高代码整齐和减少错误是好的实践。如果熟悉查询生成器,可以在表格和列网格面板中创建这个查询而不需要在SQL 面板中输入所有这些内容。关闭窗口,确认保存改变,用这个表达式更新存储过程。完成的存储过程如图5-30所示。图 5-30继续前进,关闭窗口,如果提示的话,保存任何改变。存储过程将会显示在Server Explorer树中的存储过程分支下面。下一步创建一个新报表,将这个存储过程当作数据集使用。在Solution Explorer中,右击Report,选择Add-New Item。在Add New Item对话框中,选择Report,输入报表名称Stores By Location。单击Open来创建新的报表。在报表设计器的Data选项卡,下拉Dataset列表,选择New Dataset。在这个对话框中,输入StoresByLocation作为数据集名,然后为AdventureWorks数据库选择或者创建数据源。前面已经为这个数据库创建了共享数据源。如果项目中没有共享数据源,可以参考那个练习来创建它。将Command type从Text改为StoredProcedure,然后在查询字符串框中键入存储过程名spGetStoresByLocation。结束的时候单击OK,如图5-31。设计器的外观将会变化为在右上方的下拉列表中有存储过程名的网格。单击Execute按钮(黑红感叹号标记的按钮)来测试数据集和运行存储过程。将会被提示两个参数值,StateProvinceCode和City。输入两个有效的值,然后单击OK查看结果。图5-32显示了一个例子。图 5-31图 5-32数据集和前面一样使用,存储过程参数变为报表参数。5.3.7 用报表参数筛选数据到目前为止已经在数据库级别筛选参数。有些情况用户可能在一个会议中使用同一报表按不同标准查看数据,这时从数据源中获取更大的结果集然后在报表服务器上筛选数据更为有效。正如所看到的,在查询或者作为报表数据集的存储过程中定义的参数作为报表参数传入报表。可以定义自己的参数,使用表达式在报表级别上筛选数据。我们将为报表参数使用产品类别和子类别。类别将在数据集中筛选(在SQL Server上),子类别将在报表中筛选(在报表服务器上)。在项目中添加新报表。使用AdventureWorks共享数据源。创建一个新数据集命名为ProductsByCategory,在数据集中应用下列SQL表达式:注意SQL Server 2005查询现在为每个对象引用(在这个查询里是Production)包括了一个模式前缀,类似于SQL Server 2000里的拥有者前缀。如果使用图形化查询设计器输入或者粘贴SQL代码时没有模式前缀,查询设计器将试图为每个表引用增加模式前缀。下面准备再创建两个数据集来填充参数下拉列表,在两个参数之间建立一个级联 关系。使用同一数据源,添加另一个数据集,命名为CategoryList。在查询生成器的第三个面板上输入这个文本:再添加一个数据集,命名为SubCategoryList,使用这个文本:选择报表设计器Layout选项卡,从属性窗口下拉列表中选择Report项并找到ReportParameter属性。单击这个属性边上的省略号按钮。这将打开Report Parameter对话框。注意CategoryID已经添加到报表参数中,正如所期望那样。单击Add按钮来增加一个新参数将它命名为SubCategoryID。使其他设置都为默认值来使得事情简单。单击OK来关闭ReportParameter对话框。现在切换回Data选项卡,选择Dataset下拉列表中的三个数据集的第一个,单击数据集名旁边的省略号按钮。在Dataset对话框,切换到Filters选项卡。一个筛选表达式有三个必需元素表达式(想要筛选什么)、操作符(怎样比较值)和值(筛选值的源)。对于表达式,下拉列表,选择Fields!SubCategoryName.Value。让等号操作符设置为,下拉Value列表,选择Expression。这打开了表达式生成器。使用方向控制来选择SubCategoryID参数,使用Insert按钮将它移动到对话框右边的表达式框中。结果表达式应该是Parameters!SubCategoryName.Value。使用CInt( )函数修改第一个表达式,在字段表达式两边放置括号。一些值比较不能正确解析数据类型。如果这样的比较导致数据转换或者抛出错误,可以通过显式地将表达式转换为正确的数据类型来纠正错误,正像刚才做的一样将字段表达式显式转换为一个整数。为了安全起见,可以对任何表达式或者值使用Visual Basic类型转换函数。如图5-33所示。图 5-33筛选表达式生成器有一个有趣的特性。And/Or列不允许做出显式的选择。在使用带不同值的冗余的表达式它会自动地将逻辑设为Or。如果要使用一个更复杂的表达式(例如,如果想在不选择子类别的情况下返回一个类别的所有产品),可以将其作为一个单一的表达式来手工增强。但是,使用这个工具一行一行改非常困难。关于高级筛选技术的更多信息,可以参见第6章。最后,切换到Layout选项卡,从Report菜单打开Report Parameter对话框。将SubcategoryID和CategoryID参数和它们对应的数据集关联起来,正像我们前面做的一样。确保这些参数按这个次序列出。因为有机会在几个不同的地方筛选,所以在要使用报表筛选时要仔细规划。例如,如果创建一个带分组表和图表的报表,可以为数据集、表、表分组和图表定义筛选。通常,我建议在数据集上定义筛选,除非有一个特殊的理由要定义在别处。现在有了数据集、设置了参数,可以实际地创建报表了。我们将继续保持简单。在Layout选项卡上,拖动一个文本框到报表主体,单击它以获得焦点,输入报表标题Products by Category/Subcategory。添加一个表到报表中,放在文本框下面,拉伸以填充整个报表 宽度。在表中单击一次,然后通过单击左上角的选择器来选择表。选择表的属性窗口 的DatasetName属性,选择数据集ProductsByCategory。从设计器左边的字段列表中相应 拖动ProductName、CategoryName和SubCategoryName字段到细节行的第一、第二、第 三列。通过选择标题行(在网格上单击一次,使用左边的行选择器来选择标题行)和使用报表格式化工具栏来使字体变粗来修饰网格。使用属性窗口来设置Border Style|Bottom属性为Solid,Border Width|Bottom属性为2 pt。切换到Preview选项卡。会被提示使用下拉列表选择一个类别。类别选择将会填充CategoryID查询参数和从数据库中获取记录到内存中。选择任何类别值,这时会被提示选择一个子类别值。这是报表参数SubCategoryID。选择一个值将会使引起筛选器被应用、结果数据将会送到报表中。单击View Report按钮来显示报表,如图5-34所示。图 5-34类别参数在数据库筛选数据,如图5-35所示。结果数据在报表服务器上的内存中缓存,子类别筛选器进一步限制了结果。可以容易地使用更复杂的项、排序和分组来扩展这个报表。数据集查询可以由一个存储过程所替换。有了这些构建块,读者现在有能力创建有效率的报表来在网络连接上移动合适规模的数据,允许用户使用筛选标准而不需要重新查询整个数据集。图 5-355.4 分析数据用报表近年来,高级报表及数据分析系统使得一种全新类型的数据库系统变得很受欢迎。在复杂的事务数据库系统中,商业数据量比以前要多,因此有效地为报表聚合大量数据变得越来越困难。决策支持系统在多维立方体中存储了预聚合的数据而不是在关系表中。事实上很多数据仓库系统可以利用关系数据库和多维存储的组合。决策支持数据库引擎很快成为一个高度专业化的领域。一个较为明显的不同之处在于查询这些特殊数据库的语言。其中一种最流行的语言是MDX或称多维表达式语言,它同属SQL语言一族,有SQL语言中的一些公共子句和语句,但MDX更适合用于结构数据像元组、立方体、量度和切片,而不是关系、表及字段。 SQL SERVER分析服务通过设计,分析服务数据具有层次性和多维性。不同于存储单一的事务或聚合值(或“离散数”),每次查询执行时,聚合值在预定义的分组级别存储。多维数据的视图被称为立方体,它包括维度成员(维数)和事实成员(量度和计算)。维度通常定义为分组值的层次结构。分析服务为报表进行优化。在商业数据系统演化的过程中,关系数据库系统常常会到达负荷点,在这一点数据由于如此的庞大和复杂使得查询运行缓慢。大量用户、系统共享及数据修改使得服务器资源紧张,这也同样会降低查询性能。使用分析服务实现的数据仓库和数据集市允许很多并发连接而且有更快速的查询性能。 在接下来的例子中,我将逐步引导读者完成以下过程:在基于分析服务的AdventureWoksDW数据库中定义一个数据源和数据集用来产生报表。这个示例数据库同SQL Server 2005分析服务一起被安装。如果读者已经在安装SQL Server数据库的同时将该示例数据库安装到默认路径,可以在目录c:Program FilesMicrosoft SQL SERVER90ToolsSamples目录下找到配置包。安装并连接后,就可以按照本章的步骤来用这个数据库建立示例报表。假定分析服务已经安装并配置,也有足够的权限浏览立方体和获取数据。如果没有,需要咨询本地的数据库管理员来完成。我发现,带给他们最喜欢的饮料将会有效地使得他们做好这些事情。 在这个例子中,我会给出设计一个完全的基于MDX的报表的基本步骤,但并不提供每一个步骤的详细命令。到目前为止,读者应该拥有使用这些工具及控件的必需技巧。我会提供基
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 水的电离 溶液的酸碱性与pH【学生版】-新高二化学暑假专项提升(人教版)
- 老年人外出保健知识培训课件
- 诗歌鉴赏之表达技巧-高考语文一轮复习(新高考地区专用)
- 认识社会与价值选择-2026高考政治一轮复习单元测试卷(含答案)
- 人教版高考历史一轮复习讲义-医疗与公共卫生(含解析)
- CN120201698A 一种简化变频器控制的变频器机柜
- 老师课件自我介绍
- 《喷油涡旋空气压缩机》编制说明
- 翻页时钟课件
- 2025年度商业地产商铺转租服务协议范本
- 2025年度机动车检验检测机构授权签字人考试题卷(含答案)
- 2025-2026学年北师大版小学数学六年级上册教学计划及进度表
- 2024-2025学年度辽宁现代服务职业技术学院单招《语文》检测卷有完整答案详解
- 语文开学第一课课件2025-2026学年统编版语文七年级上册
- 2025年宁夏中考数学试卷试题真题(含答案详解)
- 2025年浙江省中考语文试题卷(含答案解析)
- 2025年副科级警察面试题及答案
- 单位保安执勤方案(3篇)
- 二三轮车安全知识培训课件
- 2025云南咖啡购销合同范本
- 中职导游业务课件
评论
0/150
提交评论