Crystal Report 8非常易入门,通常只需要鼠标就可以完成报表的创建,但随着实习中对SQL语言和底层数据库的熟悉,我越来越对Crystal的“指指点点”的创建报表方式感到失望,对于存在大量表连接查询创建,SQL语言比CR(Crystal Report)的GUI界面要方便得多。
但Crystal Report 8中调用Oracle的存储过程从而直接取得数据表,并不像直接使用CR的GUI界面创建报表那样步骤明显,接下来将介绍如何在Crystal Report 8中调用Oracle Procedure的步骤,希望能对相关CR报表开发人员起到一点参考作用。
其实详细步骤在Bussiness Object的“Using Oracle Stored Procedures in Crystal Reports ”技术论文中已经有了,但我发现,对于Crystal Report 8和Oracle 9.2,并且在Oracle中程序员没有创建Package权限的情况下,具体做法仍旧有些差异:
- 从BI网站下载更新的CR到Oracle的数据库驱动,其实这个驱动也老的不行啦,不过恐怕CR 8内置的更古老
。注意一下,XP以上的操作系统,反而倒要使用cror815.zip包中的Win9x.reg来导入注册表,因为从XP开始,C:\Windows而不是C:\WinNT才是Windows的系统目录,如果你把操作系统安装在D盘,请更改相应的reg注册表文件。
- 在Oracle中创建CR要调用的procedure,比如下面这个,注意ResultCur为输入输出类型,不能只申明为输出类型,即不能将IN OUT参数改为单单OUT型的,否则随后的CR8会无法显示这样的store procedure:
procedure OperationStayTime
create or replace procedure OperationStayTime(Cust in varchar2,
StartDT
in varchar2,EndDT
in varchar2,ResultCur
in Out Sys_Refcursor) is
CURSOR c_OPST IS
SELECT CO.CONTAINERNAME,CO.CUSTOMERLOTNUMBER,
WFSTP.SEQUENCE,
OP.OPERATIONNAME,
CO.DIERELEASEDATE,
CO.TARGETDEVICE,
HML1.TXNDATE TransDate,
HML2.TXNDATE LastTransDate,
-- to be modifyed in procedure
HML2.TXNDATE HML2TXNDATE,CU.CUSTOMERNAME,
CDODEF.CDONAME,
PAK.PACKAGETYPENAME
||DI.DIMENSIONNAME||LD.LEADCOUNTNAME PDL,PTL.PRODUCTIONLINENAME,
OP.DESCRIPTION,
AMKOP.AMKORWWOPERNAME
FROM CONTAINER CO,HISTORYMAINLINE HML1,
PRODUCT PT,
HISTORYMAINLINE HML2,
MOVEHISTORY MH,
CUSTOMER CU,
CDODEFINITION CDODEF,
DIMENSION DI,
PACKAGETYPE PAK,
LEADCOUNT LD,
PRODUCTIONLINE PTL,
CURRENTSTATUS CUTSTS,
OPERATION OP,
WORKFLOWSTEP WFSTP,
AMKORWWOPER AMKOP
WHERE CO.CONTAINERID = HML1.CONTAINERID
AND CO.PRODUCTID = PT.PRODUCTID
AND CO.CURRENTSTATUSID = CUTSTS.CURRENTSTATUSID
AND HML1.CONTAINERID = HML2.CONTAINERID
AND PT.CUSTOMERID = CU.CUSTOMERID
AND HML1.TXNTYPE = CDODEF.CDODEFID
AND PT.DIMENSIONID = DI.DIMENSIONID
AND PT.PACKAGETYPEID = PAK.PACKAGETYPEID
AND PT.LEADCOUNTID = LD.LEADCOUNTID
AND CUTSTS.PRODUCTIONLINEID = PTL.PRODUCTIONLINEID
AND HML2.OPERATIONID = OP.OPERATIONID
AND HML2.WORKFLOWSTEPID = WFSTP.WORKFLOWSTEPID
AND OP.AMKORWWOPERID = AMKOP.AMKORWWOPERID
AND mh.historymainlineid = hml2.historymainlineid
AND CDODEF.CDONAME = 'Ship'
AND HML1.REVERSALSTATUS = 1
AND HML2.REVERSALSTATUS = 1
AND HML2.OPERATIONID <> '00060e08000013f1' AND -- Shipping
HML2.OPERATIONID <> '00060e08000013f0' AND -- FP Packing
HML2.OPERATIONID <> '00060e08000013ef' AND -- Schedule
CU.CUSTOMERNAME = Cust
and hml1.txndate >= to_date(nvl(StartDT, '2006/06/01 01:00:00'),
'yyyy/mm/dd hh24:mi:ss')
and hml1.txndate <= to_date(nvl(EndDT, '2006/06/01 01:00:00'),
'yyyy/mm/dd hh24:mi:ss')
ORDER BY CO.CONTAINERNAME, WFSTP.SEQUENCE;opst_rec TempOperationStayTime
%ROWTYPE;l_LastTransDate opst_rec.lasttransdate
%type;
begin
delete from tempOperationStayTime;
FOR opst_rec IN c_OPST LOOP
if l_LastTransDate is not null thenopst_rec.lasttransdate :
= l_LastTransDate;
end if;l_LastTransDate :
= opst_rec.hml2txndate;
if opst_rec.containername is not null then
INSERT INTO tempOperationStayTime VALUES opst_rec;
end if;
END LOOP;
Open ResultCur for
Select *
from TempOperationStayTime
ORDER BY CONTAINERNAME, SEQUENCE;
return;
end OperationStayTime;
- 在CR的DataExplorer中,选择More Data Sources->Oracle Server节点,在弹出的Oracle SQL对话框中分别输入User ID,Password,Server,这也是关键的一步,不能使用ODBE驱动,否则仍然不能在CR8中成功调用procedure。
- 选择刚刚添加的Server,按Options打开选项对话框,选中Show->Stored Procedures才能显示出各个储存过程,如果更改Options后Data Explorer窗口没有刷新(在CR8.0.5版本下,这肯定会发生),先收拢Server节点,再打开,CR就会按新设置刷新列表。
- 现在可以通过列表选择CR8需要调用的procedure,单击Add按钮添加要使用Oracle 存储过程。若你的储存过程有输入参数,单击Add后会要求你输入参数值,输入具体参数值,这些参数会成为Crystal Reports的Parameter Field的缺省参数,RESULTCUR是输出的数据表,不必填值。
- 完成后已经可以在Field Explorer上已经显示出存储过程返回的字段了,后面的步骤都是常规的CR8使用方法了……
