我做了一些有关异步运行报表的测试,得出一些经验,也有些问题没有解决。
基本上,提交一个异步运行的报表任务,代码如下:
DECLARE
v_repobj REPORT_OBJECT := find_report_object('report1');
v_repjob VARCHAR2(100);
BEGIN
--设置为异步运行
set_report_object_property(v_repobj, REPORT_COMM_MODE, ASYNCHRONOUS);
--如果设为RUNTIME,forms service启动reports runtime engine运行报表,结果保存在forms server上。
--设为BATCH并且指定REPORT_SERVER,报表在reports service上运行,结果保存在reports server上。
set_report_object_property(v_repobj, REPORT_EXECUTION_MODE,
BATCH);
set_report_object_property(v_repobj, REPORT_SERVER, 'REPSVR');
--异步方式下,不能设置DESTYPE为PREVIEW, SCREEN。这里设为CACHE,以后可以通过CGI到REPORT SERVER取结果。
set_report_object_property(v_repobj, REPORT_DESTYPE, CACHE);
--设置报表格式
set_report_object_property(v_repobj, REPORT_DESFORMAT, 'PDF');
--运行报表,因为异步运行方式,run_report_object立即返回了一个jobid。
v_repjob := run_report_object(v_repobj);
--我们把这个jobid保存到一个全局变量里。
:global.repjob := v_repjob;
END;
利用刚才保存的jobid,我们可以在以后取报表结果:
DECLARE
v_repjob VARCHAR2(100);
v_repstatus VARCHAR2(20);
BEGIN
v_repjob := :global.repjob;
v_repstatus := report_object_status(v_repjob);
IF v_repstatus = 'FINISHED' THEN
--报表保存在report server上,可以用rwcgi60.exe/getjobid[n]取结果。
web.show_document('rwcgi60.exe/getjobid'||v_repjob||'?server=repsvr');
END IF;
END;
上面的例子使用全局变量保存jobid,实际上我们可以将jobid保存在任何地方,例如数据库表、文本文件中。
前面讲过我的需求是希望用户提交报表后可以退出程序,下次某个时间再登录进入检查报表状态,取报表结果。我对上面代码做了一点改动,将jobid保存到表中,以后再从表中取jobid。然而测试发现了一个问题,退出程序后重新进入,report_object_status(jobid)返回null。看来report_object_status在没有调用run_report_object时使用,是无法得到报表状态的。仅管我们可以用getjobid取结果,但是我们不能看到报表状态,这是个遗憾。用户也不能接受用showjobs显示出来的报表状态,他们希望在fomrs程序中看到。