Within a PL/SQL procedure, wrap a query or refcursor in HTML table

oracleplsql

It seems really easy if you are using SQL*Plus to use

SQL> set markup html on;

and get some lovely results to the SQL*Plus window. we have an oracle job that runs overnight and sends an email of results to a number of people. I would like to wrap a sql statement in an HTML table to be in that message. What is the best way of doing that?

Best Answer

It is possible to generate xml with dbms_xmlgen, eg:

select dbms_xmlgen.getxml('select * from dual') as xml from dual;

XML
---
<?xml version="1.0"?>
<ROWSET>
 <ROW>
  <DUMMY>X</DUMMY>
 </ROW>
</ROWSET>

Using getxmltype instead, it is then possible to apply an xslt transform, perhaps like this:

select dbms_xmlgen.getxmltype('select * from dual').transform(XMLType(
'<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
  <body>
   <table border="1">
     <tr bgcolor="cyan">
      <xsl:for-each select="/ROWSET/ROW[1]/*">
       <th><xsl:value-of select="name()"/></th>
      </xsl:for-each>
     </tr>
     <xsl:for-each select="/ROWSET/*">
      <tr>
       <xsl:for-each select="./*">
        <td><xsl:value-of select="text()"/> </td>
       </xsl:for-each>
      </tr>
     </xsl:for-each>
   </table>
   </body>
</html>
  </xsl:template>
</xsl:stylesheet>')).getclobval() as html from dual;

HTML
----
<html>
<body>
<table border="1">
<tr bgcolor="cyan">
<th>DUMMY</th>
</tr>
<tr>
<td>X</td>
</tr>
</table>
</body>
</html>

nb credit to Tom Kyte for the xslt from his blog. See also this other post for a slightly more advanced version.