Using triggers with XML Publisher

Sometimes there are certain actions that need to be performed before an XML report is produced. Or certain actions have to be performed after an XML report has run (updating values in a table, kicking off the bursting engine, etc).

In the past these kind of actions were accomplished by using beforeReport and afterReport triggers in the Oracle Reports report. With the rise of XML publisher as the recommended way for producing reports it may seem that this triggers are gone.

Fortunately this is not the case. There’s still the option of using beforeReport and afterReport triggers, even if you’re only using an XML template to define the XML publisher report.
The trick is to create an XML data template which calls the triggers. The following example does exactly this.

<dataTemplate name="D_EXAMPLE1" description="Example of before and after trigger" defaultPackage="xxpvz_reporting*">
<parameters/>
<dataQuery>
  <sqlStatement name="Q1">
    <![CDATA[ select 1 field1 from dual ]]>
  </sqlStatement>
</dataQuery>
<dataTrigger name="beforeReport" source="xxpvz_reporting.init()"/>
  <dataStructure>
    <group name="G_EXAMPLE" source="Q1">
      <element name="FIELD1" value="FIELD1"/>
    </group>
  </dataStructure>
<dataTrigger name="afterReport" source="xxpvz_reporting.post()"/>
</dataTemplate>

The functions called in the dataTrigger sections need to return a Boolean value. When true is returned XML publisher “knows” all went well with the trigger. However when you return false XML Publisher will detect the trigger reported an error and will not continue. The concurrent program will get into an error state and the report will not be generated.

The example code below will start the bursting engine for the current report.

FUNCTION post RETURN BOOLEAN IS
   l_result        BOOLEAN;
   l_proc_name     VARCHAR2(240) := 'post';
   l_req_id        NUMBER;
 BEGIN
  hr_utility.set_location('Entering: '||g_package_name||'.'||l_proc_name, 10);
 
   hr_utility.trace('Try to submit bursting request');
 
   l_req_id := fnd_request.submit_request (
       application => 'XDO'
      ,program     => 'XDOBURSTREP'
      ,description => 'Bursting output'
      ,start_time  => ''
      ,sub_request => FALSE
      ,argument1   => fnd_global.conc_request_id
      ,argument2   => 'Y'
   );
 
   IF l_req_id != 0 THEN
      l_result := TRUE;
   ELSE
     hr_utility.trace('Failed to launch the bursting request');
 
     -- Put message in log
     fnd_file.put_line(fnd_file.LOG, 'Failed to launch bursting request');
 
     -- Return false to trigger error result
     l_result := FALSE;
   END IF;
 
   hr_utility.set_location('Leaving: '||g_package_name||'.'||l_proc_name, 10);
 
   RETURN l_result;
 END post;

 So the triggers are still there and can be used. Just specify them in the data template.