Crystal Reports 和sql-server共同进行报表的开发--存储过程-实践

server|存储过程

Crystal Reports 和sql-server共同进行报表的开发

1:Crystal Reports功能自述
        Crystal Reports 用于处理数据库,帮助用户分析和解释重要信息。使用 Crystal Reports 可以方便地创建简单报表,同时它也提供了创建复杂或专用的报表所需的整套工具。

        创建所能想象的任何报表
        Crystal Reports 几乎可以从任何数据源生成您需要的报表。内置报表专家在您生成报表和完成一般的报表任务过程中,会一步一步地指导您进行操作。报表专家通过公式、交叉表、子报表和设置条件格式帮助表现数据的实际意义,揭示可能被隐藏掉的重要关系。如果文字和数字确实不够充分,则用地理地图和图形进行形象的信息交流。

        将报表扩展到 Web
        Crystal Reports 的灵活性并未停留在创建报表这一功能上 ?您可以用各种各样的格式发布报表,包括用 Microsoft 的 Word 和Excel 发布、通过电子邮件甚至 Web 发布。高级的 Web 报表功能允许工作组中的其他成员在他们自己的 Web 浏览器中查看或更新共享报表。

        将报表并入应用程序
        通过将 Crystal Reports 的报表处理功能整合到自己的数据库应用程序中,应用程序和 Web 开发人员可以节省开发时间并满足用户的需求。Crystal Reports 支持大多数流行的开发语言,可以方便地在任何应用程序中添加报表。

        不论您是 IT 行业的站点管理员,还是营销推广经理,也无论您是金融业的数据库管理员还是 CEO,Crystal Reports 都堪称是一个功能强大的工具,它可以帮助每一个人分析、解释重要信息。

2:Crystal Reports和Sql-server结合
        Crystal虽然提供了强大的报表功能,但是对于复杂的逻辑运算,却是很难实现。但是,Crystal中可以像添加表一样添加存储过程,这就给我们的复杂运算提供了简便的处理方法。

3:例子
 这是我们给国航公司it服务项目做的报表的sql-server存储过程部分。(欢迎大家共同讨论)
A:每个员工的处理故障完成数、总数
    fgw_proc1.txt

--fgw_proc1 处理故障完成数、总数
CREATE PROCEDURE  [AHD].[fgw_proc1](@开始时间 datetime , @结束时间 datetime)
AS
    DECLARE @begin int , @end int                     /*转时间*/
    exec fgw_util1 @开始时间, @begin output
    exec fgw_util1 @结束时间, @end output

    DECLARE @userid int, @handled float, @total float

    CREATE TABLE #temp_proc1
    (
    userid int,
    handled float,
    total float
    )
   
    DECLARE cur_ctct CURSOR FOR SELECT id FROM AHD.AHD.ctct --取所有的用户id
    OPEN cur_ctct
    FETCH cur_ctct INTO @userid
    WHILE @@FETCH_STATUS = 0
        BEGIN
 --get @handle through exec fgw_proc2
 EXEC fgw_proc1_1 @userid , @begin , @end , @handled output , @total output  /*call下个存储过程,得到某个用户的解决数、接触故障数*/
             INSERT INTO #temp_proc1 VALUES (@userid , @handled , @total)    /*将用户信息插入临时表*/
 FETCH NEXT FROM cur_ctct INTO @userid    /*记录下移*/
        END
    CLOSE cur_ctct
    DEALLOCATE cur_ctct
    SELECT * FROM #temp_proc1  /*生成结束集*/
    DROP TABLE #temp_proc1      /*释放*/
GO

    fgw_proc1_1.txt

--fgw_proc1_1
CREATE PROCEDURE [AHD].[fgw_proc1_1](@userid int , @begin int , @end int , @handled float OUTPUT , @total float OUTPUT)
AS

    SET @handled = 0
    SET @total = 0
    DECLARE @cr_id int, @zh_id int, @status char(12), @to_status char(12), @cnt int, @open_date int
    --handled /*计算此人的处理完成故障数*/
    DECLARE cur11_1 CURSOR FOR SELECT AHD.call_req.id AS cr_id, AHD.ztr_his.id AS zh_id, AHD.call_req.status, AHD.ztr_his.to_status, AHD.ztr_his.to_cnt AS cnt, AHD.call_req.open_date FROM AHD.call_req LEFT OUTER JOIN AHD.ztr_his ON AHD.call_req.persid = AHD.ztr_his.call_req_id WHERE AHD.call_req.type='I' AND (AHD.call_req.status IN ('CL', 'TTPC')) AND (AHD.ztr_his.to_status IN ('L1WIP', 'L2WIP', 'ICP', 'SRBYL1', 'SRBYL2', 'NCCBYL1', 'NCCBYL2', 'CRBYL1', 'CRBYL2')) AND AHD.call_req.open_date>@begin AND AHD.call_req.open_date<@end AND AHD.ztr_his.to_cnt = @userid
    OPEN cur11_1
    FETCH cur11_1 INTO @cr_id, @zh_id, @status, @to_status, @cnt, @open_date  /*事件id,历史id,状态,处理人,打开时间取所需要的值*/
    WHILE @@FETCH_STATUS = 0    /*循环每一个记录*/
        BEGIN
        DECLARE @count2 int    /*每个事件单在历史记录中有多少条*/
            DECLARE cur11_2 CURSOR FOR SELECT count(*) FROM AHD.call_req LEFT OUTER JOIN AHD.ztr_his ON AHD.call_req.persid = AHD.ztr_his.call_req_id WHERE AHD.call_req.type='I' AND (AHD.call_req.status IN ('CL', 'TTPC')) AND (AHD.ztr_his.to_status IN ('L1WIP', 'L2WIP', 'ICP', 'SRBYL1', 'SRBYL2', 'NCCBYL1', 'NCCBYL2', 'CRBYL1', 'CRBYL2')) AND (AHD.call_req.open_date>@begin) AND (AHD.call_req.open_date<@end) AND (AHD.call_req.id = @cr_id)
        OPEN cur11_2
        FETCH cur11_2 INTO @count2
        CLOSE cur11_2
        DEALLOCATE cur11_2
        IF @count2 <> 0
            SET @handled = @handled + 1.0 / @count2  /*此人的处理完成数*/
        FETCH NEXT FROM cur11_1 INTO @cr_id, @zh_id, @status, @to_status, @cnt, @open_date  /*循环记录*/
        END
    CLOSE cur11_1
    DEALLOCATE cur11_1   
    
    --total /*计算此人的处理故障数*/
    DECLARE cur11_3 CURSOR FOR SELECT count(distinct(AHD.call_req.id)) FROM AHD.call_req LEFT OUTER JOIN AHD.ztr_his ON AHD.call_req.persid = AHD.ztr_his.call_req_id WHERE AHD.call_req.type='I' AND (AHD.call_req.open_date>@begin AND AHD.call_req.open_date<@end) AND (AHD.ztr_his.to_cnt = @userid) /*取此人所有单*/
 
    OPEN cur11_3
    FETCH cur11_3 INTO @total /*总故障数*/
    CLOSE cur11_3
    DEALLOCATE cur11_3

    --SELECT @handled
    --declare @handled float,@total float
    --exec fgw_proc1_1 400115,1,1111111111,@handled output ,@total output
    --print @handled
    --print @total
GO

B:每个员工的响应达标数、响应总数
    fgw_proc2.txt
--fgw_proc2 响应达标数、响应总数
CREATE PROCEDURE [AHD].[fgw_proc2](@开始时间 datetime , @结束时间 datetime)
AS
    DECLARE @begin int , @end int
    exec fgw_util1 @开始时间, @begin output
    exec fgw_util1 @结束时间, @end output

    DECLARE @cr_id int, @zh_id int, @cnt int, @sym char(30), @time_stamp int, @isOK int , @userid int , @handled int , @total int
    DECLARE @call_req_id char(30)

    CREATE TABLE #temp_proc2   /* 响应达标数、响应总数*/
    (
    userid int,
    handled2 int,
    total2 int
    )

 CREATE TABLE #temp_proc2_1 /* 事件单为op的记录*/
    (
    cr_id int,
    zh_id int,
    cnt int,
    isOK int
    )

    --initialize #temp_proc2_1 /*已经op的单,是否响应达标,返回处理人*/
    DECLARE cur2_1 CURSOR FOR SELECT zh.call_req_id,zh.id,zh.to_cnt,sd.sym,zh.time_stamp FROM AHD.AHD.call_req as cr LEFT OUTER JOIN AHD.AHD.ztr_his as zh ON cr.persid=zh.call_req_id LEFT OUTER JOIN AHD.AHD.srv_desc as sd ON cr.support_lev=sd.code WHERE cr.type='I' and cr.open_date>@begin and cr.open_date<@end and  (zh.to_status='ASTOL1' OR  zh.to_status='ASTOL2')
    OPEN cur2_1
    FETCH cur2_1 INTO @call_req_id, @zh_id, @cnt, @sym, @time_stamp  /*事件单id,历史单id,人员,服务级别,op状态的时间*/
    WHILE @@FETCH_STATUS = 0
        BEGIN
        EXEC fgw_proc2_1 @call_req_id , @sym , @time_stamp , @isOK output
        INSERT INTO #temp_proc2_1 VALUES (@cr_id , @zh_id , @cnt , @isOK)
        FETCH NEXT FROM cur2_1 INTO @call_req_id, @zh_id, @cnt, @sym, @time_stamp
        END
    CLOSE cur2_1
    DEALLOCATE cur2_1 

    --initialize #temp_proc2
    DECLARE cur2_2 CURSOR FOR SELECT id FROM AHD.AHD.ctct
    OPEN cur2_2
    FETCH cur2_2 INTO @userid
    WHILE @@FETCH_STATUS = 0
        BEGIN
        --get @total  /*所有的已响应的单*/
        DECLARE cur2_3 CURSOR FOR SELECT count(*) FROM #temp_proc2_1 WHERE cnt = @userid
        OPEN cur2_3
        FETCH cur2_3 INTO @total
        CLOSE cur2_3
        DEALLOCATE cur2_3

        --get @handled  /*所有的已响应的单,并达标的单*/
        DECLARE cur2_4 CURSOR FOR SELECT count(*) FROM #temp_proc2_1 WHERE cnt = @userid AND isOK=1
        OPEN cur2_4
        FETCH cur2_4 INTO @handled
        CLOSE cur2_4
        DEALLOCATE cur2_4

        INSERT INTO #temp_proc2 VALUES (@userid , @handled , @total)
        FETCH NEXT FROM cur2_2 INTO @userid
        END
    CLOSE cur2_2
    DEALLOCATE cur2_2
    DROP TABLE #temp_proc2_1
    SELECT * FROM #temp_proc2
    DROP TABLE #temp_proc2
GO

    fgw_proc2_1.txt
--fgw_proc2_1
CREATE PROCEDURE  [AHD].[fgw_proc2_1](@call_req_id char(30) , @level char(30) , @time_stamp int , @isOK int OUTPUT)
AS
    SET NOCOUNT ON
    SET @isOK = 0

    DECLARE cur_zh CURSOR FOR SELECT time_stamp FROM AHD.AHD.ztr_his WHERE call_req_id = @call_req_id and to_status in ('L1WIP','L2WIP') and time_stamp>@time_stamp
    OPEN cur_zh
    DECLARE @time_stamp1 int
 SET @time_stamp1=0

    FETCH cur_zh INTO @time_stamp1
 IF (@time_stamp1 is not null) and  (@time_stamp1<>0)
 BEGIN
  IF CHARINDEX('一级', @level) IS NOT NULL AND CHARINDEX('一级', @level)<>0
   BEGIN
    if @time_stamp1 - @time_stamp <600
    SET @isOK=1
   END
  ELSE IF CHARINDEX('二级', @level) IS NOT NULL AND CHARINDEX('二级', @level)<>0
   BEGIN
    if @time_stamp1 - @time_stamp <1800
    SET @isOK=1
   END
  ELSE IF CHARINDEX('三级', @level) IS NOT NULL AND CHARINDEX('三级', @level)<>0
   BEGIN
    if @time_stamp1 - @time_stamp <1800
    SET @isOK=1
   END
  ELSE IF CHARINDEX('四级', @level) IS NOT NULL AND CHARINDEX('四级', @level)<>0
   BEGIN
    if @time_stamp1 - @time_stamp <1800
    SET @isOK=1
   END
 END

    CLOSE cur_zh
    DEALLOCATE cur_zh
    --SELECT @isOK, @time_stamp1
GO

C:每个员工的处理时限达标数,总数
    fgw_proc3.txt
--fgw_proc3
CREATE PROCEDURE fgw_proc3(@开始时间 datetime , @结束时间 datetime)
AS
    /*时间转换*/
    DECLARE @begin int , @end int
    exec fgw_util1 @开始时间, @begin output
    exec fgw_util1 @结束时间, @end output

    DECLARE @cr_id int, @zh_id int, @cnt int, @sym char(30), @time_stamp int, @isOK int , @userid int , @handled int , @total int

    CREATE TABLE #temp_proc3
    (
    userid int,
    handled2 int,
    total2 int
    )

    DECLARE cur3_2 CURSOR FOR SELECT id FROM AHD.AHD.ctct
    OPEN cur3_2
    FETCH cur3_2 INTO @userid
    WHILE @@FETCH_STATUS = 0
        BEGIN
        --get @handled
        DECLARE cur3_4 CURSOR FOR SELECT distinct(cr.id) FROM AHD.AHD.call_req as cr LEFT OUTER JOIN AHD.AHD.ztr_his as zh ON cr.persid=zh.call_req_id WHERE cr.type='I' and cr.open_date>@begin and cr.open_date<@end and zh.to_cnt = @userid and cr.sla_violation=0
        OPEN cur3_4
        SET @handled = @@CURSOR_ROWS
        CLOSE cur3_4
        DEALLOCATE cur3_4

        --get @total
        DECLARE cur3_5 CURSOR FOR SELECT distinct(cr.id) FROM AHD.AHD.call_req as cr LEFT OUTER JOIN AHD.AHD.ztr_his as zh ON cr.persid=zh.call_req_id WHERE cr.type='I' and cr.open_date>@begin and cr.open_date<@end and zh.to_cnt = @userid
        OPEN cur3_5
        SET @total = @@CURSOR_ROWS
        CLOSE cur3_5
        DEALLOCATE cur3_5

        INSERT INTO #temp_proc3 VALUES (@userid , @handled , @total)
        FETCH NEXT FROM cur3_2 INTO @userid
        END
    CLOSE cur3_2
    DEALLOCATE cur3_2
    SELECT * FROM #temp_proc3
    DROP TABLE #temp_proc3

D:将日期格式转换成整型
    fgw_util1.txt

--fgw_util1
CREATE PROCEDURE [AHD].[fgw_util1] (@time datetime, @seconds int output)
AS
   set @seconds=datediff(ss,'1970-01-01 00:00:00', @time)
GO

例子只是整盘拷贝了代码,欢迎大家共同讨论

时间: 2024-10-18 16:44:38

Crystal Reports 和sql-server共同进行报表的开发--存储过程-实践的相关文章

在SQL Server 2005中如何列出所有存储过程

为了查找这些存储过程,你可以花时间在互联网搜索,查看一些你还未知道的存储过程,也许在一两个小时您可能会发现你想要...也许你很幸运的找到,其他人在他们的文章中列出所有的存储过程 ,函数和视图,并介绍了如何使用这些存储过程. 但其实,您可以在一分钟之内就可以自己列出这些存储过程.函数和视图的清单!这份名单甚至包括SQL Server中所有无文档的存储过程.通过这个清单,你就可以确定你所想要找的存储过程. SQL Server 2005实际上保存了所有存储过程的列表,包括有文档的.无文档的,甚至是用

在IIS中为SQL Server 2008配置报表服务

不知道是不是SQL Server 2008的Bug,我在安装了SQL2008后(选择了安装报表服务的),但是在IIS中 根本没有报表服务的虚拟目录.只是这么一个问题,其他BI设计器.报表服务等都还算正常. 要正常使用报表服务则需要手动添加报表服务的虚拟目录,具体操作如下: (1)运行inetmgr打开IIS管理器. (2)新建应用程序池Report,使用默认配置即可,该应用程序池用于报表服务专用. (3)在默认网站中新建虚拟目录Reports,本地路径是C:\Program Files\Micr

SQL Server 2008中报表服务详解

一.导言 尽管公司经常采集和存储大量的数据,但是有时还是难以详尽地显示数据,而且也很难提供对商业中 将发生什么的洞察以使商业决策者为公司作出相应的和及时的决策. 为了能作出有效的商业决策,公司内从业务经理到信息工作人员的所有层级的用户需要能很容易的访 问到直接提供信息的综合了从企业内多个数据源获得的数据的报表.在大多数公司里,这些报表需要结合 详细的数字和基于文本的报表,这些报表提供了对公司活动的全面的说明和图形化的可视化,它帮助使得 可以更好的查看趋势和进行比较. 报表服务为公司提供了满足各种

SQL Server 2008升级报表服务器数据库

报表服务器数据库可以为一个或多个报表服务器实例提供内部存储.因为报表服务器数据库架构可能会因为推出新的 Reporting Services 版本而有所变化,所以要求数据库版本与使用的报表服务器实例的版本相匹配.大多数情况下,报表服务器数据库可以自动升级,您不需要执行任何具体操作. 如何升级报表服务器数据库 以下列表指出了升级报表服务器数据库的所有情况: 安装程序升级报表服务器的单个实例.在服务启动并且报表服务器确定数据库架构版本与服务器版本不匹配之后,将自动升级数据库架构. 服务启动时,报表服

SQL Server 2005的数据挖掘功能的最佳实践

作为向用户销售个性化铃声和其它可以被下载到手机的内容提供商,需要时刻和市场保持同步,了解用户需求.ABS-CBN Interactive公司(以下简称为ABSI)是菲律宾最大的综合性媒体和娱乐公司ABS-CBN广播公司的子公司,ABSI公司通过搜索它自己的在线交易(OLTP)数据来向客户提供有价值的交叉销售信息.但是这个搜索需要很多天时间才能够完成,不能够为客户提供个性化建议.ABSI公司希望通过提高系统的响应速度从而在商业活动中占据主动地位,以增加销售额. 通过和微软商务智能金牌合作伙伴 dB

SQL SERVER 2000 的零成本(开发、实施)方案

server SQL Server 企业版.标准版.开发人员版的正版价格都很高,一般的用户或者开发企业都难买得起 而接触过MSDE的人都知道,MSDE是微软推出的一个免费的SQL桌面引擎.它限制了同时访问用户的数量,而内核与其它版本基本相当.最大为同时5人访问.并且不附带客户端管理工具,不方便调试.安装.而SQL Server 标准版和企业版则无此限制,而且附带客户端工具 我的安装方案如下首先安装MSDE,然后随便找一个SQL Server 的安装光盘,安装一个SQL客户端.然后启动客户端的服务

Sql Server Tempdb原理:日志机制解析实践

笔者曾经在面试DBA时的一句"tempdb为什么比其他数据库快?"使得95%以上的应试者都一脸茫然.Tempdb作为Sqlserver的重要特征,一直以来大家对它可能即熟悉又陌生.熟悉是我们时时刻刻都在用,陌生可能是很少有人关注它的运行机制.这次我将通过实例给大家介绍下tempdb的日志机制. 测试用例 我们分别在用户数据库(testpage),tempdb中创建相似对象t1,#t1,并在tempdb中创建创建非临时表,然后执行相应的insert脚本(用以产生日志),并记录执行时间用以

SQL Server 2008 R2的发布订阅配置实践

    纸上得来终觉浅,绝知此事要躬行.搞技术尤其如此,看别人配置SQL SERVER的复制,发布-订阅.镜像.日志传送者方面的文章,感觉挺简单,好像轻轻松松的,但是当你自己去实践的时候,你会发现还真不是那么一回事,毕 竟环境不同.数据库版本或经验关系,你实践的时候会或多或少碰到一些问题,有可能人家是多次实践后,绕开了那些"坑",毕竟写文章是事后总结,人家台上一 分钟,台下十年功.闲话不扯了,进入正题,本文虽然简单,但是趁现在有时间,也记录一下前几天配置Replication的发布订阅

SQL Server查找包含某关键字的存储过程3种方法

例子1  代码如下 复制代码 select OBJECT_NAME(id),id from syscomments where id in ( select object_id(name) from dbo.sysobjects where xtype='P' ) and text like '%FieldName%' group by id 例子2 在数据库SQL Server 2005/2008中,查询包含某关键字的存储过程语句:  代码如下 复制代码 select distinct b.n