Search code examples
sqloracleselectcursoralias

Can I alias columns from a cursor in SELECT statement in Oracle?


I am writing a client application that calls a stored procedure from an Oracle database via a select statement. The stored procedure returns a cursor. I need to define aliases for the columns returned by this cursor, and I need to do it within my select statement.

I cannot make any changes to the Oracle database. I cannot write any PLSQL. The only thing I can do with this database is query it.

Please advise.


Background: This stored procedure is one of many called inside an application framework. Currently, all calls return their results in XML format, using this syntax to do the conversion:

select XMLType.createXML(package_name.storedProcName('1', '2', '3')).getClobVal() as sresult  from dual;

However, this cursor contains two columns with the same name (specifically "NAME"). When this query is run in TOAD, the column automatically gets appended a "_1", however the XMLType results in illogical XML, like this:

<?xml version="1.0"?>
<ROWSET>
    <ROW>
        <ID>1</ID>
        <NAME>BRUCE WAYNE</NAME>
        <NAME>BATMAN</NAME>
    </ROW>
</ROWSET>

This is why I must alias the columns before they are converted to XMLType. I want the query output to contain no duplicate column names so that the XML can be like this instead (with no duplicate tags):

<?xml version="1.0"?>
<ROWSET>
    <ROW>
        <ID>1</ID>
        <NAME>BRUCE WAYNE</NAME>
        <OTHER_NAME>BATMAN</OTHER_NAME>
    </ROW>
</ROWSET>

Solution

  • i would go for a stylesheet for this.

    eg:

    SQL> select XMLType.createXML(foo()).transform(xmltype('<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      2  <xsl:template match="/ROWSET/ROW/NAME[2]">
      3     <NAME_1>
      4             <xsl:apply-templates select="@*|node()"/>
      5     </NAME_1>
      6  </xsl:template>
      7  <xsl:template match="@*|node()">
      8     <xsl:copy>
      9             <xsl:apply-templates select="@*|node()"/>
     10     </xsl:copy>
     11  </xsl:template>
     12  </xsl:stylesheet>')) as sresult  from dual
     13  /
    
    SRESULT
    --------------------------------------------------------------------------------
    <ROWSET>
      <ROW>
        <ID>1</ID>
        <NAME>BRUCE WAYNE</NAME>
        <NAME_1>BATMAN</NAME_1>
      </ROW>
      <ROW>
        <ID>2</ID>
        <NAME>CLARK KENT</NAME>
        <NAME_1>SUPERMAN</NAME_1>
      </ROW>
    </ROWSET>
    

    i.e. we replace the 2nd NAME occurrence (/ROWSET/ROW/NAME[2]) in the ROW element with NAME_1. everything else gets copied as-is.