本文转自:http://blog.csdn.net/deepsea_allen/article/details/53900284
第三章 创建一个分组报表
1. 建立数据模型
数据模型用于定义一个报表中使用的数据及数据结构,这些数据可以是数据库表中的原始数据,也可以是经过加工后的数据,如工资的总和等。从数据库中检索出的数据是否在报表输出中显示,也是在数据模型中定义的。
数据模型由五部分对象组成:查询(Queries)、组(Groups)、列(Columns)、连接(Links)和参数(Parameter)。
1) 建立查询
查询实际上就是一条SQL SELECT语句,决定了从数据库中指定的表或视图中取哪些行和列。查询所取得的数据可被用于计算、排序、集合运算等,并可以在报表输出时显示。
Ø 报表中的查询可分为两种:内部查询和外部查询。两者的区别在于外部查询可以被其他报表多次引用,而内部查询不能被其他报表参考引用,只能被其所属的报表引用。
Ø 根据报表中查询的个数可以将报表分为单查询报表和多查询报表。
单查询报表:只有一个查询的报表称为单查询报表。单查询报表的常见格式有列表式(Tabular)、标签式(Mailing Label)、信封式(Form Letter)以及分组式。单查询报表虽然只有一个查询,但可以多次显示查询数据,并且可以用不同的格式显示。
多查询报表:含有多个查询的报表称为多查询报表。多个查询相互之单可以有关联,称为相关的多查询报表;也可以没有关联,称为不相关的多查询报表。
l 相关的多查询报表:多个查询之间相互关联,一般用于主从式报表,也就是说,报表的一部分数据决定了报表的另一部分数据。取出前一部分数据的查询称为主查询,取出后一部分的查询称为从查询,主查询的每一条记录查询都将引起从查询的执行,从查询只检索与主查询匹配的那些记录。两个查询之间通过定义数据连接产生联系。
l 不相关的多查询报表:多个查询之间没有关联,Oracle Reports将独立地为每一个查询获取数据,显示出来的是一系列不相关的数据。
查询之间运行的先后次序由数据模型中的查询次序决定。在数据模型中,查询次序是先上后下,先左后右,所以放在左上角的查询最先执行。
示例:为避免数据冗余,我们这里将订单头和行分别建立两个查询:
a) 在对象管理器中选中报表,右击打开“报表编辑器”,然后点击打开“数据模型”。
b) 点击SQL查询创建两个查询。
c) 修改Q1->Q_header,G_order_number->G_header;
Q2->Q_line,G_line_num->G_line
2) 建立数据连接
数据连接用于建立两个查询数据之间的关系。在数据模型编辑器中,两个查询之间的连线即表示了一个数据连接。
工作原理:数据连接通过主键和外部键定义了两个查询之间的主/从关系。主/从关系中父查询的每一条记录的产生都会引起子查询的执行,子查询只检索满足在连接中指定的条件的记录。
通常情况下,两个查询之间的连接是等值连接,但也可以采用SQL语句(如WHERE、HAVING、START WITH等)建立非等值连接。
当一个带有数据连接的报表执行时,该数据连接就被转换成一个SQL子句,并添加到子查询的后面。子查询根据父查询的主链值执行查询。
建立方法:一种是手动建立的数据连接,一种是自动建立的数据连接。
手动连接的步骤:在数据模型编辑器中选择:“数据连接”小图标;
单击父查询的主链列或外部键列,并拖动鼠标到子查询的主链或外部键列,使它们之间建立一条连线。注意,连线总是从父查询到子查询的;
自动连接的步骤:在数据模型编辑器中选择:“数据连接”小图标;
单击父查询,并拖动鼠标到子查询上,系统会自动显示父查询和子查询之间是依据哪个列建立连接的;
示例:点击数据连接,创建从Q_header (header_id)到Q_line(header_id1)的数据连接。
3) 建立组
组对象主要有两个功能:
Ø 将一个查询的数据分成几个集合,每个集合称为组。例如,将“EMP”表按“DEPTNO”分组,结果显示如下:
Ø 过滤查询数据,通过组可以对查询的结果进行过滤。
在Oracle Reports中将组分为缺省组和用户定义组两类:
Ø 在缺省的情况下,Oracle Reports为数据模型中的每一个查询产生一个组,取名取成查询的名称。查询名称以“Q_”开头,而组名以“G_”开头。例如,查询名称为“Q_header”,则Oracle Reports为其产生的缺省组名为“Q_header”。
Ø 用户定义组可用于以下三种情况:分组报表;矩阵报表;子汇总。
组过滤器允许有条件的选择由查询检索出来的数据,通过组过滤器过滤查询结果。
有两种类型的组过滤器:Oracle Reports封装过滤器和用户定义过滤器。
Ø Oracle Reports封装过滤器允许指定在一个组中希望检索的记录数,在报表开发过程中可以使用封装过滤器来限制数据。Oracle Reports软件包中有两个封装过滤器:First Filter,只显示组内前n条记录;Last Filter,只显示组内后n条记录。
Ø 用户定义过滤器:用户可以定义自己的过滤器来限制在特定条件下的记录的检索。用户定义的过滤器是通过编写PL/SQL代码建立的。
数据模型中组的层次决定了在缺省布局对话框中组的次序,同时也决定了在缺省布局中组的次序,但这不是最终的报表格式,因为可以对缺省的显示格式进行修改。
在数据模型编辑器中若没有数据连接,则组的层次是由组在数据模型编辑器中的位置从左至右,从上至下决定的。在数据模型编辑器中若有数据连接,则组的层次可以由数据连接描述。通过对象导航器可以清晰地看到组的层次:
4) 定义列
报表的列表示报表的数据。在定义了从数据库检索数据的查询后,可能需要进一步调整报表,增加更多的列,而这些列可以用作报表的数据,执行总计汇总等功能。
Oracle Reports中的列可以分为两类,缺省列和用户定义列。
Ø 缺省列
Oracle Reports为查询SELECT语句中的每一项都建立一个列,因为它们直接对应从数据库中检索出来的各个列,所以缺省列也叫数据库列。
Oracle Reports除了支持典型的数据类型的列(如字符型、数值型、日期型)以外,还支持图型列。图型列的值可能是:
直接存储在数据库中的图型:这种列的数据类型通常是RAW或LONG RAW。在这种情况下,需在列的属性选项板中指明图形格式。
文件名或者是图型的URL:这种列的数据类型通常是REF,列中的值对应于用指针指向一个存在操作系统中的文件,报表输出时会根据指针将文件内容输出,在这种情况下,需在列的属性选项板中将“Read from File”设置为“Yes”并输入文件名。文件名前可以带有路径,若文件名前没有带有路径,则Oracle Reports会按照其路径搜索顺序查找文件。可以通过Report Builder的环境变量REPORT30_PATH来设置搜索路径。注意,若列的属性选项板中“Read from File”被置为“No”并且输入了文件名,则报表最后输出的只会是文件名,而不会是文件内容。
Oracle Reports支持多种图形格式,包括BMP、CALS、CGM、GIF、JFIF、PCD、PCX、PICT、RAS、TIFF等。
Ø 用户定义列
用户可在特定的组内或报表一级建立列。在特定的组内建立的列称为组一级的列,该列与组内的其他列有相同的显示频度。而报表一级的列只在整个报表中显示一次。用户定义列分为三种类型:公式列、占位列和汇总列。
a) 公式列,公式列是对其他列执行一个用户定义的计算。建立公式列的方法是用PL/SQL语句写一个函数,从一个或多个列中计算结果,该列的缺省名为“CF_n”。
示例:在G_line组中定义一个的公式列newAmount,来显示Amount *1.06的值。
在数据模型编辑器中单击:“公式列”小图标。如果要在组中建一个公式列,则在画布的组区域内单击一下鼠标左键,如果要建一个报表一级的公式列,则在画布的空白区域内单击一下鼠标左键,会生成一个公式列对象;
双击该公式列对象,弹出其属性选项板;
点击属性选项板中的“PL/SQL公式”项,弹出“程序单元编辑器”;
在“程序单元编辑器”中为公式项用PL/SQL语句书写一个计算公式并编译通过。
b) 占位列,占位列的值和数据类型是通过PL/SQL语句设置的,该列的缺省名为“CP_n”。当需要有选择地设置一个列的值时(例如,在每次出现第n个记录时,或每次出现包含有特殊值的记录时)占位列非常有用。
可以在以下几个地方设置占位列的值:
在Before Reports的报表触发器中(如果占位列是一个报表级的列);
在报表级的公式列中(如果占位列是一个报表级的列);
在占位列组或占位列组下面的公式中(为组中的每一条记录设一次值)。
占位列的用途:
在公式列的PL/SQL代码中计算出的一些值可以分配给不同的占位列;
利用占位列保存中间值。例如,存储当前检索出的最高工资对应的记录。
c) 汇总列,汇总列是对其他列的数据执行计算。Oracle Reports为汇总列提供的计算函数有:总和、平均值、最小值、最大值、计数、第一个、最后一个、%(总计)、标准差、方差。
示例:在G_header组中添加CS_countAmount,来计算订单行的总金额;
在Report级别添加CS_total,来计算订单的总数量;
在数据模型编辑器中单击“汇总列”小图标,如果要在组中建立一个汇总列,则在组中你希望该列所在的位置上单击一下鼠标左键,如果要建一个报表一级的汇总列,则在画布的空白区域内单击一下鼠标左键,会生成一个汇总列;
双击该汇总列对象,弹出其属性选项板;
从属性选项板中的“汇总”项下的“功能”子项的下拉列表中选择所需的计算公式;在“源”子项中选择要汇总的列名;
在“重设于”子项中选择汇总的频度,即是就整个报表做一次汇总还是每一页做一次汇总,或者每一组做一次汇总;
当“功能”子项被选为“%(总计)”时,“计算于”项有用,其值为计算“%(总计)”的汇总列时的组名。该项只对“%(总计)”有用。
5) 参数
参数是报表变量,在报表运行过程中,用户可以为其指定不同的值。参数主要用于在运行过程中修改SELECT语句和设置PL/SQL变量。Oracle Reports中的参数分为两类:系统参数和用户参数。
Ø 系统参数
系统参数又称缺省参数。Oracle Reports允许为每一个报表修改标准的运行设置,系统参数共有7个。
系统参数 |
功能 |
取值 |
省缺值 |
COPIES |
报表输出到打印机的份数 |
任何整数 |
1 |
DESFORMAT |
输出设备的格式,如:打印机 |
Dflt、Pslan80 |
Dflt |
DESNAME |
输出设备的名字,如:文件名、打印机名 |
||
DESTYPE |
输出结果送到什么地方,如屏幕、文件、邮件、打印机等 |
File、Mail、Screen、Printer |
Screen |
MODE |
报表运行的模式,如:字符界面、图形界面等 |
Bitmap、Character |
Default |
ORIENTATION |
打印报表输出时的打印方向,如:Landscape、Portrait |
Landscape、Portrait |
Landscape、Portrait |
PRINTJOB |
当运行一个报表时是否显示“PRINT JOB”对话框 |
YES、NO |
YES |
Ø 用户参数
用户参数是用户建立的一个对象,该对象用于保存在运行时用户可以改变的值。在一个查询的任何地方都可以引用用户的参数,用户参数主要用于以下几个方面:
l 在SELECT语名的WHERE子句中用参数替代常数作限制值。
l 用参数替代SELECT语句的任何部分,包括选择列、表,甚至整个SELECT语句。
l 在SELECT列表中用参数替换一个单列或一个表达式。
引用参数的方法主要有两种:连接引用和置换引用。
a) 连接引用
连接引用主要用于替换SQL语句和PL/SQL块中的一个值或表达式。
使用连接引用的方法是在要引用的参数前加上“:”号。
连接引用的使用受以下限制:不能在SELECT语句中替换列名;不能在FROM从句中使用连接引用;不能替代保留的单词和子句。
示例:将查询Q_header的where条件中写死的条件:
oh.order_numberbetween 29480and29485
修改为:oh.order_numberbetween:p_order_fromand:p_order_to
保存修改后,Oracle Report会自动加入这两个用户参数。
b) 置换引用
置换引用可以用参数替代SELECT语句的任何部分,如替换列名、FROM子句、WHERE子句、GROUP BY子句、ORDER BY子句、HAVING子句、CONNECT BY子句、START WITH子句等。
使用置换引用的方法是在要引用的参数前加上“&”符号。
注意:不能在PL/SQL中使用置换引用,但可以在PL/SQL中使用连接引用。
和连接引用不同的是,对于置换引用的参数,用户必须事先在对象导航器中建立,并且在属性选项板中为其输入初始化值,Oracle Reports不会缺省地建立该参数。
举例:使用置换引用替代列名和FROM子句。
SELECT &P_ENAME NAME, &P_EMPNO ENO
FROM &P_EMP;
这样可以动态地根据运行时输入的参数值,决定从哪个表检索那些列。
使用置换引用替换WHERE子句
SELECT * FROM EMP &P_WHERE;
在运行时可任意指定WHERE子句,根据不同的限制条件检索所需数据。
值列表,为参数值建立值列表,这样,在运行时用户就可以从该值列表中选择一个有效值。可以限制用户只能选择值列表中的值,也可以允许用户输入其他的值。
对于连接引用的参数,值列表可以是一个不能修改的静态的值列表,也可以是在运行时从数据库中动态地选择值的动态值列表。
对于置换引用的参数,值列表只能是静态的。
2. 设计布局
布局的功能是定义报表的格式,包括数据文本及图形的位置和显示格式。
在布局模型编辑器中将报表布局分为三个区域:表头区域、表尾区域和主体区域,每个区域又分为主体和页边距。
Ø 表头区域 在报表每一页的开头显示一次,表头区域可以包含文本、图形、数据及其运算。
Ø 表尾区域 在报表每一页的结尾处显示一次,表尾区域可以包含文本、图形、数据及运算。
Ø 主体区域 出现在表头和表尾之间,是报表的主要部分。当第一次进入一个新报表的布局模型编辑窗口时,所处的位置就对应着报表的主体区域。主体区域包含报表的主要文本、图形、数据及其运算。
基本布局对象:
在布局模型编辑器中,是通过定义和修改布局对象来实现的,Oracle Reports中的基本布局对象有框架(Frames)、重复框架(Repeating Frames)、域(Fields)、图文(Boilerplate)、定位(Anchors)、按钮(Buttons)、OLE2对象、Oracle Graphics对象。
1) 框架
框架用来围绕其它布局对象。一个框架可以包含任何布局对象,包括其它的框架。框架的打印次数与它所围绕的对象的打印次数一样,框架与记录无关。
框架的主要用途:
l 把对象组织在一起,以保证在打印时它们之间的相对位置;
l 避免覆盖其他对象和被其他对象覆盖;
l 将报表划分为几个部分。例如,在每一页的顶部采用列表式的报表格式,而在底部采用钜阵式的报表格式;
l 确保一些对象总是在相同的页中。
框架分为两种类型:缺省框架和用户定义框架。
缺省框架,当接受缺省的布局模型时,Oracle Reports会自动生成包含对象的框架。缺省框架的命名形式为“M_n”。缺省框架又可分为两种:垂直可变的组框架和固定尺寸的框架。例如,当创建最初缺省的布局模型时,Oracle Reports产生一个围绕整个布局模型的组框架,这个组框架在垂直方向上是可伸缩的。而固定尺寸的框架通常是围绕图文对象(Boilerplate)建立的,例如列的标题。
用户定义框架,用户定义的框架是在布局模型编辑器中通过“框架”工具建立的。
框架的重要属性:
l 在这之前分页(Page Break Before):指示在打印该对象前进行换页。
l 在这之后分页(Page Break After):指示在打印完该对象后进行换页,在其后面的对象都将移到下一页打印。
l 页保护(Page Protect):指示对象内的所有对象尽可能地打印在一个页内,如果一个页容纳不下的话,在开始打印该对象时会先换页。
l 垂直缩放值(Vertical Elasticity):指示对象的垂直大小是否可以改变,有:收缩、扩展、固定、可变。
l 水平缩放值(Horizontal Elasticity):指示对象的水平大小是否可以改变,有:收缩、扩展、固定、可变。
l 打印对象在(Print Object On):指示对象在报表的打印频率,有:全部页、除首页外的全部、除尾页外的全部、缺省、第一页、最后一页。
l 基于以下环境打印(Base Print On):指示对象是以定位对象还是以包含对象为基准进行打印。
l 跟随定位对象(Keep With Anthoring Object):指示对象是否跟随定位对象打印在同一个逻辑页中。
2) 重复框架
重复框架主要用于显示由一个组检索出来的多行数据的对象。一个重复框架可以包含任何布局对象,也可以包括其它的重复框架。重复框架是与记录相关的,它为一个组的每一条记录及其所关联的数据模型对象都打印一次。使用重复框架可以控制记录层的显示和格式,比如:记录的打印方向、记录的空隙、边框线、颜色、字体等。重复框架的箭头方向指明了重复框架重复的方向。
嵌套的重复框架常常用于建立主/从表和分组表。
重复框架分为两种类型,缺省的重复框架和用户定义的重复框架。
缺省的重复框架,当接受缺省的布局模型时,Oracle Reports会自动地为数据模型中的每一个组生成一个重复框架,并且为组中的每一列都对应安排一个域,放在重复框架内。
用户定义的重复框架,用户定义的重复框架是在布局模型编辑器中通过“重复框架”工具建立的。
重复框架的几个重要属性:
l 源(Source):每一个重复框架必须有一个源(组)作为其数据来源,在重复框架中每一条源数据显示一次;
l 打印方向(Print Drection):重复框架中记录的打印方向,有:横向、纵向、横向/纵向、纵向/横向;
l 每页的最大记录数(Maximum Record per Page):在逻辑页上显示的重复框架记录的最大数目,可以通过该属性改善报表的可看性。例如,希望在每个逻辑页上只显示三条记录,则将该属性设置为3。该属性的取值可以为正整数和空,若为空,则尽可能在一个逻辑页上显示最大数目的记录。
l 最小孤立记录数(Minimum Widow Records):必须在一张逻辑页上显示的最少记录数。若从逻辑页的指定位置开始放不下此属性中给出的记录数,则将从下一张逻辑页开始显示。。例如下图,有两个独立的重复框架按纵向打印,第二个重复框架位于第一页的底部,但第一页上仅有打印两条记录的空间了,为了使报表看起来更美观,我们希望第二个重复框架换记录能从第二页开始打印,这时就需要将“最小孤立记录数”设置为3。
l 列模式(Column Mode):用于控制如何为重复框架中的记录提取数据和格式化数据。这个属性有两个选项:“是”和“否”。若选“是”,则允许在上一个重复框架的记录没有打完之前就打印下一个重复框架的记录。例如,若设置“列模式”为是,则虽然记录2直到第二页才打完,但记录3却可以开始在第一页上打印了。若设置:“列模式”为“否”,则记录3只能等到记录2打印完后,才开始在第二页上打印。
l 水平框架间隔:重复框架记录间的水平间隔。当打印方向为“纵向”或“纵向/横向”时,该属性的设置无效。
l 垂直框架间隔:重复框架记录间的垂直距离。当打印方向为“横向”或“横向/纵向”时,该属性的设置无效。
3) 域
域是用来放置参数、列、页号、当前日期等值的地方。例如一个参数或列没有对应的域,那么它的值不会在报表输出时显示。当生成一个缺省布局模型时,Oracle Reports会自动地为每一个列建立一个域,并将这些域排放在重复框架中。
域有两种类型:缺省域和用户定义域。
缺省域,当接爱缺省的布局模型时,Oracle Reports会自动地为每一列产生一个域,并将这些域排放在重复框架中。每一个域的属性都是缺省生成的,但是可以修改。
用户定义域,用户可以根据需要定义一些域来显示诸如页号、日期等信息。
用户定义的域是在布局模型编辑器中通过“域”工具建立的。
域的数据来源有三种:数据模型的中的一个列或参数、系统变量和系统参数。
系统变量包括:当前日期(¤t date)、页码(&logical page number)、面板数值(&panel number)、物理页码(&physucal page number)、总记页(&total logical pages)、总记面版(&total panel)、总计物理页(&total physical pages)
域的属性:
l 源(Source):域值的来源。
l 源数据来源(Source Data Type):源的数据类型,此属性为只读。
l 可视的(Visible):若设置为“否”,则表示该域不被格式化。这一属性公用于那些在图文对象中引用的域,通常用于格式信件式报表。若想引用一个“可视的”属性设置为“否”的域,可以在图文对象中输入“&fieldname”。
l 格式掩码(Format Mask):定义以何种格式显示在域中的日期和数值。有值列表可供选择,但是字符型的域没有该属性。
l 编页码(Page Numbering):当域的源列是页码、物理页码、总记页、总记物理页之一时,可以使用该属性来定义如何计算页号。点击:编页码按钮,出现“编页码”对话框。
4) 图文
图文是一个查询获取不到但又要在报表中输出的对象,如文本、线条、图形等。可以使用图文对象来改变报表的外观,例如建立报表的页头、增加图形等。
图文有两种类型:缺省的图文和用户定义的图文。
缺省的图文,当接受缺省的布局模型时,Oracle Reports会自动地为每个域生成一个列标题。对于某些报表类型,Oracle Reports会在列标题下加一条下划线。
用户定义的图文,一种是通过图文工具新建的一个图文,一种是从外部文件输入的图文。
从外部文件输入图文,可以用“导入”工具或者使用“链接文件”工具来链接一个文件。
链接一个文件,只是建立了一个指针,指向要连接的文件,并不将文件的内容输入到图文对象中,所以在每一次运行报表时,都动态地将文件内容输入到图文对象中,因此,图文对象中的内容是动态的,会随着文件内容的改变而改变,采用这种方式,能保证报表的输出总是反映最新的内容,这种方式是在布局模型编辑中通过“链接文件”工具建立的。
5) 定位
定位是用于确定报表输出时子对象相对于其父对象的水平和垂直位置。由于在运行报表时,有些布局尺寸会发生变化,所以需要用定位来定义一个对象相对于另一个对象的位置。
例如,对于一个水平方向大小可变的重复框架,希望它里面的一个域总是位于重复框架水平方向的中间位置,同时又希望该域与重复框架的顶部保持固定距离,由于重复框架是水平方向大小可变的,因此其将来实际输出时的水平尺寸是不可预知的,所以需要定义一个定位来实现以上目的,如下图所示。
用定位连接的两个对象之间的相对位置关系是基于数据取出数据之后的对象的实际尺寸,而不是对象在布局模型编辑器中的尺寸。布局模型编辑器中对象间相对位置实际上反映了报表输出对象的位置。
定位分为两种类型:隐式定位和显示定位。
隐式定位,Oracle Reports会自动地为每个没有显示定位的布局对象生成一个隐式定位,以防止该对象被其他对象覆盖。隐式定位节约了用于定义每个对象的位置的时间。
在对象导航器中,若采用“对象类型视图”,则看不到隐式定位,但可以看到显示定位。若采用“所有权视图”,则缺省情况下看不到定位的,要想看到定位,须打开“工具”菜单中的“选项”->“导航器”,弹出“对象导航器选择”对话框,在“布局”栏中选中“定位信息”,则会在导航器中显示所有的定位信息,包括隐式定位和显示定位。
但隐式定位在布局模型编辑器中总是不可见的。
显示定位,显示定位是在布局模型编辑器中通过“定位”工具建立的,通过显示定位可以强制性地将某些对象放在一起。当一个对象在水平或垂直的大小可能会随着许多记录的增减而改变时,或者在决定一个对象相对于重复框架的相对位置时,显示定位尤其有用。
3. 设计报表布局的注意事项
1) 设计布局前的参数设置
点击菜单“工具”->“选项”->“标尺”
2) 在数据模型和布局模型的编辑页面中的,可以点击菜单“视图”来选择是否显示标尺,网格等辅助设计的面板,尤其是“工具面板”一定要选择显示。
3) 最外层固定框的属性“打印对象在”必须设置为“第一页”。
4) 表头的“打印对象在”必须设置为“全部页”。
5) 要实现自动分页,必须将最外层的固定框或循环框“打印对象在”设置为“第一页”。
6) 可以在循环框外面加一个固定框,并将固定框的属性更改为“可变”,固定框的输出会紧接着循环框的位置。
4. 参数表格
当运行一个报表时,Oracle Reports会弹出一个窗口,称为参数表。可以在此窗口中输入参数值,从而屏蔽原有的缺省值。
如果没有建立报表参数表格,在运行时,Oracle Reports将会自动建立一个参数表格以供用户输入参数,但当报表运行完后,这个参数表格的内容就会自动地被删除。
Oracle Reports提供缺省的参数表格样式,可以采用缺省的参数表格,也可以在缺省参数表格的基础上进行修改,或者建立用户自已定义的参数表格。
建立缺省的参数表格:
点击菜单“工具”->“参数表单创建器”
修改“标题”、“提示行”和“状态行”的内容,它们将显示在运行参数表的顶端;
根据需要选中要在运行参数表中出现的参数,被选中参数的背景色为黑色,如上图中,参数“P_ORDER_FROM”被选中,则该参数将会出现在运行参数表中,用户可以为它输入新值,而不使用其缺省值。注意,这里未被选中的参数不会出现在缺省的参数表格中。
建立用户自定义的参数表格:
双击对象导航器中的“页面参数表单”
在这里,只能建立两种对象:域对象和图文对象。
Ø 域对象:域对象是用来放置参数值的地方。如果某一参数没有定义与其相应的域对象,则在运行参数表上不会显示该参数。缺省情况下,Oracle Reports会为每一个参数建立一个域对象。也可以通过使用“报表编辑器-参数表格”中的“域”工具建立一个域,然后将一个已有的系统参数或用户定义参数分配到该域。
Ø 图文对象:图文对象的作用和在布局模型中的作用一样。缺省情况下,Oracle Reports会生成运行参数表的“标题”、“提示行”和“状态行”图文对象,并为每个域建立一个标签图文对象。也可以通过使用“报表编辑器-参数表格”中的“图文”工具建立额外的图文对象以增强运行参数表的可观性。
5. Oracle Reports触发器
在Oracle Reports中,触发器可分为三类:
Ø 报表触发器:共有5个报表触发器,分别在运行报表的不同阶段被触发。
Ø 数据模型触发器:包括公式列触发器、组过滤触发器、参数验证触发器。其中,公式列触发器在每次处理列时被触发,组过滤触发器可以由组中的每一条记录触发,参数验证触发器在显示参数表格和用户离开参数域时被触发。
Ø 布局格式触发器:在处理布局对象时触发。
1) 报表触发器,是用户在运行报表和设置报表格式时,在指定时刻执行的PL/SQL函数。这些报表触发器允许用户执行以下操作:调整报表格式、执行初始化任务、访问数据库。
系统定义了五个报表触发器,用户可以修改触发器的内容,但不能创建新的报表触发器。
Before Parameter Form
在显示运行参数表之前被触发,即使参数表被隐藏起来不显示,此触发器仍然可以被触发。它用于存取并修改参数值、PL/SQL全局变量和报表组列值。通常利用此触发器来检验命令行参数。
After Parameter Form
在显示运行参数表之后触发,即使参数表被隐藏起来不显示,此触发器仍然可以被触发。该触发器用于存取、校验和修改参数值。如果在运行中出现错误,则返回到运行参数表。该触发器不能存取数据模型中的列。
Before Reoprt
该触发器在分析查询语法和检索数据之后、运行报表之前被触发,用于执行初始化处理各种参数。
Between Pages
除去第一页以外,该触发器在每一页报表被格式化之前被触发,用于页的格式化设置。在预览器中,此触发器只在第一次进入该页时被触发,如果后续再进入该页,则此触发器不再被触发。
After Report
该触发器在退出预览器后或将报表输出到目的地(如:文件、打印机或Oracle*Mail用户标识)以后初触发,用于清除对参数的初始化处理,如删除临时表。无论报表是否成功执行,此触发器一直是处于激活状态。
2) 数据模型触发器
公式列触发器,是指在公式列中编写一个PL/SQL函数,该列又可以构造其他对象,如占位列或公式列本身。
公式列中的代码必须返回给公式列,此列可以是一个“虚”列,既在报表的布局模型中不被显示出来。
例:
目的:希望当员工工资大于3000时,奖金显示的是工资乘以0.1,否则奖金显示出的是工资乘以0.5,并给出提示。
实现方法:使用公式列构成两个占位列“BONUS”和“BONUS_CHAR”,根据不同条件给这两个列赋值。
- FUNCTION SET_BONUS RETURN CHAR IS
- BEGIN
- IF :SAL > 3000 THEN
- :BONUS := :SAL * 0.1;
- :BONUS_CHAR := 'ten percent';
- ELSE
- :BONUS := :SAL * 0.1;
- :BONUS_CHAR := 'ten percent';
- END IF;
- RETURN '';
- END;
FUNCTION SET_BONUS RETURN CHAR IS
BEGIN
IF :SAL > 3000 THEN
:BONUS := :SAL * 0.1;
:BONUS_CHAR := 'ten percent';
ELSE
:BONUS := :SAL * 0.1;
:BONUS_CHAR := 'ten percent';
END IF;
RETURN '';
END;
由于该公式列是一个虚列,因此函数返回一个空字符串。
组过滤器,组过滤器用于限制出现在报表中的记录的行数。组过滤器对数据的限制是在检索数据之后,在显示数据之前,所有使用组过滤器并不能减少由查询语句检索出来的数据总量,若想减少由查询语句检索出来的数据,可以在查询语句中使用WHERE子句进行限制。
Oracle Reports提供了两个组过滤器:前几个(First)和后几个(Last)。用户还可以编写自己的组过滤器。
组过滤器只能由两个返回值:
Ø TRUE:表示提取组中指定的数据。
Ø FALSE:表示不提取组中指定的数据。
另外,组过滤器不能用于交叉分组。
验证触发器,用户可以在系统参数和用户自定义的参数中编写验证触发器,用于检测输入到运行参数表中的参数值,如果参数不正确,则停止报表运行。
验证触发器必须返回一个布尔值(TRUE或FALSE)。若返回为FALSE,则光标会停留在参数中,用户可以输入不同的值或则退出报表的运行。
示例:验证用户输入的订单号范围是否合理
- FUNCTION P_ORDER_TOValidTrigger return boolean IS
- BEGIN
- IF :P_ORDER_TO < :P_ORDER_FROM THEN
- RETURN (FALSE);
- ELSE
- RETURN (TRUE);
- END IF;
- END;
FUNCTION P_ORDER_TOValidTrigger return boolean IS
BEGIN
IF :P_ORDER_TO < :P_ORDER_FROM THEN
RETURN (FALSE);
ELSE
RETURN (TRUE);
END IF;
END;
3) 布局格式触发器
大多数的布局对象都含有一个布局格式触发器,它是布局对象的一个公共属性。布局格式触发器存在于以下对象中:框架、重复框、域和图文对象。
布局格式触发器允许用户在报表运行时根据一定条件动态地修改布局对象的显示或隐藏。
4) 动作触发器
动作触发器是在预览器中选中一个按钮时执行的PL/SQL过程。该触发器可以动态地调用另一个报表或执行PL/SQL程序。在动作触发器中输入的PL/SQL过程,可参考Oracle Reports中的封装函数、过程和异常处理。
6. Oracle Reports中的PL/SQL
用户可以将PL/SQL用于Oracle Reports对象中以增加报表功能。
1) 在PL/SQL中引用报表对象
在PL/SQL中引用报表对象有两种方法:
变量值引用,通过在Oracle Reports对象前加一个“:”号来引用Oracle Reports对象值。
例如,要使ORDER_NUM列的值为1000,则输入:ORDER_NUM:= 1000
变量名引用,通过用单引号括起Oracle Reports对象来引用对象的名称。
例如,要使变量FIELDNAME等于F_NAME域的名称,FIELDNAME := ‘F_NAME’
2) Oracle Reports中的PL/SQL块
Oracle Reports中能使用以下9种方法的PL/SQL结构块:
PL/SQL程序库(external libraries)、附件的程序库(attached libraries)
程序单元(report program units)、报表触发器(report triggers)
组过滤器(group filters)、公式(formula)、验证触发器(validation triggers)
格式触发器(format triggers)、动作触发器(action triggers)
PL/SQL:PL/SQL程序库、程序单元;
Trigger&Filters:重复框、框架、域、图文、参数、组、报表触发器;
Formula:公式列;
Button Triggers:按钮;
3) Oracle Reports中的PL/SQL异常处理
通常有三种类型的异常处理:
Ø 用户定义的异常处理,具体方法参考PL/SQL技术文档。
Ø 标准封装的异常处理,是Oracle系统预先定义的例外,同参考PL/SQL技术文档。
Ø Oracle Reports特有封装的异常处理,Oracle Reports特有的例外定义在SRW包中,具体有:
SRW.CONTEXT_FAILURE SRW.RUN_REPORT_FAILURE
SRW.DO_SQL_FAILURESRW.RUN_REPORT_BATCHNO
SRW.INTEGER_ERROR SRW.TRUNCATED_VALUE
SRW.MAXROW_INERRSRW.UNKNOW_QUERY
SRW.MAXROW_UNSETSRW.UNKNOW_USER_EXIT
SRW.NULL_ARGUMENTS SRW.USER_EXIT_FAILURE
SRW.PROGRAM_ABORT
异常处理的使用规则:
Ø 如果用户没有处理一个异常,那么Oracle Reports会替用户去处理它,既在异常处理被激活时,Oracle Reports将产生一个错误,终止报表的执行。
Ø 用户必须在当前PL/SQL域中测试结构块的失败情况。
例如,如果用户给公式列编写了PL/SQL代码,那么该公式列必须测试它自己的失败情况,其他对象甚至另一个公式列是不能对它的失败进行测试。
4) SRW包
为了方便用户使用,Oracle Reports提供了一个封装的包,称为SRW。它是一组PL/SQL结构块的集合,包含了许多可在库和报表中引用的函数、过程和异常处理。用户可以在库或报表中参考引用它们。
当用户在PL/SQL结构块中参考SWR包时,必须加上前缀SRW,例如SRW.DO_SQL。
SRW包的用途有:控制报表的运行、在运行时输出信息、初始化域对象、执行DDL语句(建立/删除临时表)、调用用户接口、动态地设置布局对象属性、如字体和填充模式等。
可以在报表中的任何PL/SQL语句中引用SRW包的任何部分,但是,SRW包中的内容只能在Oracle Reports中被引用,不能在其他工具(如Oracle Forms)中被引用。
SRW包由下列结构块组成:
SRW.BREAK SRW.CONTEXT_FAILURE
SRW.DO_SQL SRW.DO_SQL_FAILURE
SRW.GETERR_RUN SRW.GET_PAGE_NUM
SRW.INTEGER_ERROR SRW.MAXROW_INERR
SRW.MAXROW_UNSETSRW.MESSAGE
SRW. NULL_ARGUMENTS SRW.PROGRAM_ABORT
SRW.REFERENCE SRW.RUN_REPORT
SRW.SET_ATTR SRW.RUN_REPORT_FAILURE
SRW.RUN_REPORT_BATCHNO SRW.SET_FIELD_CHAR
SRW.SET_FIELD_DATE SRW.SET_FIELD_NUM
SRW.SET_MAXROW SRW.TRACE_ADD_OPTION
SRW.TRACE_END SRW.TRACE_REM_OPTION
SRW.TRACE_START SRW.TRUNCATED_VALUE
SRW.UNKNOWN_QUERY SRW.UNKNOWN_USER_EXIT
SRW.USER_EXIT SRW.USER_EXIT20
SRW.USER_EXIT_FAILURE
7. 程序单元和附加的程序库
1) 程序单元(Program Units)
程序单元是指从当前报表中的任何PL/SQL库中参考引用的包、函数和过程。程序单元不能被其他程序参考。若想创建一个能被多个程序参考引用的包、函数或过程,需要创建一个PL/SQL程序库。
2) 附加的程序库(Attached Libraries)
对于一些比较通用的函数和过程,或者逻辑比较复杂的函数和过程,我们可以把它们集合在一起写成一个PL/SQL程序库。一个PL/SQL程序库就是一个PLL库文件。
在报表中,我们可以采用附加的程序库的方式来引用它。对于附加程序库,用户可以在报表中调用它的包、函数和过程。
Ø 建立PL/SQL程序库
PL/SQL程序库,即PLL文件,需要在Reports Builder中去建立。
详细的建立过程如下:
a) 在对象导航器中选择“PL/SQL库”节点,然后单击工具栏上的“创建”工具,则在“PL/SQL库”节点下会出现一个新的库结点,该节点下有两个子节点:“程序单元”子节点和“附加的库”子节点。
b) 选中“程序单元”子结点,然后单击工具栏上的“创建”工具,弹出“新建程序单元对话框。
c) 在对话框中输入过程、函数、包说明或包主体的名称,接受对话框,则弹出“程序单元编辑器”窗口。
d) 输入PL/SQL过程、函数、包的代码,编译后关闭“程序单元编辑器”窗口。
e) 点击保存按钮,保存库文件到指定的目录中。
Ø 连接PL/SQL程序库
建立好PL/SQL程序库后,库中的所有函数、过程都可以在任何Oracle产品中被引用。但在引用前,须将库连接到引用它的报表上。
连接步骤如下:
a) 在对象导航器中选择“附加的库(Attached Libraries)”节点,然后单击工具栏上的“创建”工具,则弹出“附加程序库(Attach library)”对话框。
b) 先在对话框中输入PL/SQL库的名称,或者点击“浏览”来选择要附加的PL/SQL程序库文件。然后再单击“附加”按钮来连接该PL/SQL程序库。
c) 系统会提示“附加的程序库的名称包含不可移植的目录设置,要删除此路径吗?”,一般我们会选择“Yes”,这样附加的库文件和路径无关,只要把库文件放在REPORTS60_PATH所指定的路径下系统就可以找到。如果选“No”,则附加的库文件带有绝对路径,库文件的位置不能改变,不利于报表安装。
将建立好的PL/SQL程序库附加在报表上后,程序库库中的所有函数、过程、包就可以在报表的任何地方被调用。