存储过程是由流控制和SQL语句书写的过程,这个过程经编译和优化后存储在数据库服务器中,FienReport使用时只要调用即可。
调用Oracle存储过程主要有两步:第一步,定义存储过程;第二步,调用存储过程。
下面以一个具体的实例来学习如何使用FineReport调用Oracle存储过程的。
第一步,Oracel定义存储过程
StScroe是Oracele数据库中的张表,其中记录了学生的成绩信息,表结构如下:
图 1
定义返回列表的存储过程——由于oracle存储过程没有返回值,它的所有返回值都是通过out参数来替代的,列表同样也不例外,但由于是集合,所以不能用一般的参数,必须要用pagkage了,所以定义存储过程要分两部分:
1.建立一个程序包,如下:
CREATE OR REPLACE PACKAGE TESTPACKAGE ASTYPE Test_CURSOR IS REF CURSOR;END TESTPACKAGE;
2.建立存储过程,存储过程为:
CREATE OR REPLACE PROCEDURE p_STSCORE(Class in varchar2,p_CURSOR out TESTPACKAGE.Test_CURSOR) ISBEGINOPEN p_CURSOR FOR SELECT * FROM FR.STSCORE where STSCORE.ClassNo=Class;END p_STSCORE;
第二步,调用存储过程
1.启动FineReport设计器,右击数据源面板,选择私有数据源,弹出私有数据源对话框。
2.点击增加按钮,新建一个私有数据源,名为ds1,数据库选择为Oracle数据源,查询类型为存储过程,在sql文本框中写如下语句调用存储过程:
{call fr.p_stscore('[?Class|Class1?]',?)}
图 2
3.点击预览按钮,可以预览查询到的数据,如下所示:
图 3
至此,FineReport设计器成功调用Oracle存储过程,您可以根据报表需求随心所欲地设计报表样式了。
第四个技巧:灵活使用COUNT函数。
在查询处理的时候,COUNT函数可以说是我们应用的比较多的函数之一。如我们有时候需要统计员工的人数、统计图书的种类数的时候,都需要使用到这个函数。不过,这个函数很多人可能会用,但是到灵活应用的地步,还是有一点差距。
下面笔者就COUNT函数的一些应用技巧谈谈自己的心得。
一是要灵活放置COUNT函数的位置,因为利用COUNT函数统计记录数的时候,是会考虑空行的记录的。如在数据表中一般有序列字段与其它的有意义字段两类。有时候可能序列字段中有内容而其它字段中没有内容,则在利用COUNT函数统计记录数量的时候,会把这个空记录也考虑进去。很明显,则就会发生统计的错误。所以,这个COUNT函数该放在哪个位置上,还是比较讲究的。一般的话,笔者试建议不要放在序列号字段上,而要放在一些关键的实体字段中。如统计员工人数的时候,则就可以放在员工姓名或者编号上等等。
二是灵活跟其它函数搭配使用。如在上面的例子中,笔者谈到有时候用户需要知道现在有员工编制的部门与职位有哪一些,我们可以利用DISTINCT函数来找出具体的部门。但是,我现在只想知道有编制的部门与职位具体有多少,此时,我们也可以利用COUNT 与DISTINCT函数结合应用,找出我们所需要的数据。在COUNT函数中,可以指定ALL与DISTINCT选项。默认的情况下,是ALL选项,表示统计所有的行,其中也包括重复的行。而DISTINCT就表示只统计不重复的行。可见,COUNT函数跟其它函数搭配使用的话,可以简化我们的查询语句,提高查询效率。
第五个技巧:只查询必须的字段。
有时候,用户不同的查询需求都要用到同一张表。如在员工信息表中包含了很多内容。有时候用户想要知道正式员工有多少;管理层员工有多少;生产线员工又有哪些;或者想知道合同即将到期的员工有哪些。为此,就遇到一个问题,因为这些内容基本上都是在同一张表中,那是在同一个视图中实现,而是根据需求不同,设计不同的视图呢?
若单从技术上考虑,两这都是可以实现的,不会有多大的难度。但是,若是从数据库性能上考虑在,则还是采用不同的视图来实现不同的需求为好。
一方面,若从安全方面讲,则可以根据不同的视图来控制相关的访问权限。可见,把视图细化,在权限控制上则会更加的灵活。
另一方面,数据的查询效率,跟数据内容的多少也有非常密切的关系。如在查询员工合同到期信息的时候,一般不需要员工的地址信息等等。若把这个信息也查询出来的话,由于这个字段比较长,就会花费比较长的时间。所以,在数据库设计中,我们要学会根据用户不同的需求,设计不同的视图。虽然可能这在设计的时候会比较花时间,但是,在确可以提高数据库的性能与安全性。这笔生意还是划得来的。