对于希望用存储过程解决的复杂数据源问题,可以考虑采用润乾集算器esProc来实现。


在性能方面,集算器基于Java,代码解释执行的速度要快于存储过程自身的控制代码。集算器提供并行执行能力,可以充分利用普通计算机和PC服务器来实现分布式计算集群,可获得远远超过存储过程的性能。

如果业务允许,可以考虑将数据库中的报表相关数据移到文件系统中,利用集算器的计算能力为报表提供数据源。可以在有效降低数据库压力的同时,进一步提高报表性能。


在编程难度方面,集算器解决了SQL固有的问题,更接近人们的自然思维,可以更快速的写出报表数据计算程序,也非常容易读懂、维护。用集算器解决同样问题的代码长度要远远少于存储过程。

而且,集算器是跨平台和数据库的,非常容易移植。也可以从多种数据库、文件中取数,统一进行计算。

同时,集算器提供功能强大的集成开发环境(IDE),降低编程工作量,提高代码调试的效率。


在代码管理方面,集算器的程序文件可以在操作系统中形成树形的结构,形成多层分类管理。

集算器的程序文件可以和Java文件一样进行基本的配置管理。如果需要的话,可以导出成文本文件进行更细致的版本管理。


在系统维护方面,集算器是在应用服务层运行的,程序改动无需数据库权限,不会带来数据安全上的问题。

集算器的程序之间是通过函数的方式调用的,只要函数的接口不变,函数内部的变化不会影响其他程序。

值得一提的是,集算器提供功能强大的免费版本,而且提供JDBC接口,非常容易和现有的报表工具集成,项目组可以考虑逐步引入。

最后,我们通过一个具体的例子,来看一下集算器和存储过程实现报表数据源计算的代码对比。


某电信产品厂商有一张报表,主要目的是分析优势产品的销售额、销量、环比等指标,其中优势产品的定义是在每个州的销量均在前10名的产品,数据主要存储在stateSales table,其数据结构如下:

wKiom1Oo8cSCh-siAABwwfXsMxM084.jpg


计算优势产品,看看存储过程和集算器是如何进行数据准备的。


Oracle存储过程:

01  createorreplacepackage salesPkg

02  as

03     type salesCur isrefcursor;

04  end;

05  CREATEORREPLACEPROCEDURE topPro(io_cursor OUTsalesPkg.salesCur) 

06  is

07    varSql varchar2(2000);

08    tb_count integer;

09  BEGIN

10  selectcount(*) into tb_count from dba_tables where table_name='TOPPROTMP';

11  if tb_count=0then

12   strCreate:='CREATE GLOBAL TEMPORARY TABLE TOPPROTMP (

                     stateTmp NUMBERnot null,

                     productTmpvarchar2(10)  not null,

                     amountTmpNUMBER not null

              )

              ON COMMIT PRESERVE ROWS';

13  executeimmediate strCreate;

14  endif;

15  executeimmediate'truncate table TOPPROTMP';

16  insertinto TOPPROTMP(stateTmp,productTmp,amountTmp)

selectstate,product,amount from stateSales a

wherenot(

         (a.state,a.product) in (

selectstate,product from stateSales groupby state,product havingcount(*) >1

         )

androwidnotin (

selectmin(rowid) from stateSales groupby state,product havingcount(*)>1

         )

       )

orderbystate,product;

17  OPEN io_cursor for

18  SELECT productTmp  FROM (

SELECTstateTmp,productTmp,amountTmp,rankorder

FROM (SELECT stateTmp,productTmp,amountTmp,RANK()OVER(PARTITIONBY stateTmp ORDERBY amountTmp DESC) rankorder 

FROM TOPPROTMP

         ) 

WHERE rankorder<=10orderby stateTmp

    )

GROUPBY productTmp 

HAVINGCOUNT(*)=(SELECTCOUNT(DISTINCT stateTmp ) FROM TOPPROTMP);

END;


    用集算器esProc

wKioL1Oo8Zbi07n-AACVdQ4IyPY040.jpg