Skip to Main Content
  • Questions
  • Ways to Name the Output Columns of a Pipelined Table Function

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Martin.

Asked: May 02, 2019 - 8:41 am UTC

Last updated: May 02, 2019 - 4:38 pm UTC

Version: 18c

Viewed 1000+ times

You Asked

How many ways are there to name the output columns of a pipelined table function?
My understanding is the only way is via a RECORD type like this:

CREATE PACKAGE blah_blah_blah IS
  TYPE abc_rec IS RECORD (ID       NUMBER,
                          SUBJECT  VARCHAR2(30),
                          BODY     VARCHAR2(4000));

  TYPE abc_rec_table IS TABLE OF abc_rec;

  FUNCTION xyz RETURN abc_rec_table PIPELINED;
END blah_blah_blah;

SELECT *
FROM   blah_blah_blah.xyz;

ID  SUBJECT        BODY
==  ===========    ========
 1  Subject One    Body One
 2  Subject Two    Body Two
 3  Subject Three  Body Three



I had hoped that it was possible to name them after cursor columns, but that results in the columns being named: ATTR_1, ATTR_2, ATTR_3, etc. instead.

CREATE PACKAGE blah_blah_blah IS
  CURSOR C1 IS
    SELECT CAST(ID      AS NUMBER)          AS ID,
           CAST(SUBJECT AS VARCHAR2(30))    AS SUBJECT,
           CAST(BODY    AS VARCHAR2(4000))  AS BODY
    FROM   <my table>;

  TYPE abc_rec_table IS TABLE OF C1%ROWTYPE;

  FUNCTION xyz RETURN abc_rec_table PIPELINED;
END blah_blah_blah;

ATTR_1  ATTR_2         ATTR_3
======  =============  ========
   1    Subject One    Body One
   2    Subject Two    Body Two
   3    Subject Three  Body Three

and Chris said...

I don't know of a way to override the ATTR* names you get when using cursor-based data types.

So I believe you have to use records (or object types) as in your first example.

Rating

  (2 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

from 12.2 database.

Rajeshwaran, Jeyabal, May 02, 2019 - 3:01 pm UTC

Sorry dont have an 18c to test with, but with 12.2 the column in the output has the names aliased as per the cursor columns.

demo@PDB1> create or replace package mypkg
  2  as
  3     cursor c is select
  4             cast( owner  as varchar2(30) ) as x1,
  5             cast( object_name as varchar2(60) ) x2,
  6             cast( created as date ) as x3
  7     from all_objects
  8     where rownum <=3 ;
  9
 10     type cur_tab is table of c%rowtype;
 11     function foo return mypkg.cur_tab pipelined;
 12  end;
 13  /

Package created.

demo@PDB1> create or replace package body mypkg
  2  as
  3     function foo return mypkg.cur_tab pipelined
  4     as
  5             l_data cur_tab;
  6     begin
  7             open c;
  8             fetch c bulk collect into l_data;
  9             close c;
 10
 11             for i in 1..l_data.count
 12             loop
 13                     pipe row( l_data(i) );
 14             end loop;
 15             return ;
 16     end;
 17  end;
 18  /

Package body created.

demo@PDB1> select * from table( mypkg.foo );

X1         X2                   X3
---------- -------------------- --------------------
SYS        ORA$BASE             08-MAR-2017
SYS        DUAL                 08-MAR-2017
PUBLIC     DUAL                 08-MAR-2017

demo@PDB1>
demo@PDB1>

Chris Saxon
May 02, 2019 - 4:38 pm UTC

Interesting. I see the same in 12.2. Looks like this is something that changed in 18c. I'm not sure why.

It's like this in 19c too, which you can see in this Live SQL script: https://livesql.oracle.com/apex/livesql/file/content_IBYPQ5XC76JGAXOZTH6KK0QM1.html

It's a bug

Stanislav, August 23, 2019 - 3:10 pm UTC

It's a bug since +18.X, release.
Bug 28672457 : COLUMN ALIAS IS NOT HONORED IN THE RESULT SET FROM PIPELINE FUNCTION IN 18C

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library