Home » SQL & PL/SQL » SQL & PL/SQL » How can we access an object type(not table of objects) in Oracle TABLE function? (Oracle 10R2)  () 1 Vote
How can we access an object type(not table of objects) in Oracle TABLE function? [message #611943] Thu, 10 April 2014 05:46 Go to next message
balaji.chelladurai
Messages: 6
Registered: April 2014
Junior Member
How can we access an object type(not table of objects) in TABLE function ?

The table function works on a collection of objects, but I have a need to access a single row using TABLE function.

I get the error "ORA-22905: cannot access rows from a non-nested table item" when I try to use TABLE function with an object type instead of collection of object types.

The workaround that I use is to create a table type collection on this object and place the row in the first index, and then use the table type in the function. Any other simple solutions ?

I need to query the object as if it is a row in a table.This is to have a common code base in my application to support two different use cases.

With a common code base, I can use the same SELECT query to query the records either from an actual table or from a single-row object using TABLE function. Only the FROM clause of the Dynamic SQL changes.

CASE 1:
Querying a physical table

v_select := 'SELECT a,b,c,d '
v_from := ' FROM ' || v_actual_table
v_where := '<where_predicate>

EXECUTE IMMEDIATE v_select || v_from || v_where;


CASE 2:
Querying a row object using TABLE function. The row object is coming from Oracle AQ channel in the form of messages.

v_select := 'SELECT a,b,c,d '
v_from := ' FROM TABLE(:1)'
v_where := '<where_predicate>

EXECUTE IMMEDIATE v_select || v_from || v_where USING v_table_type;
Re: How can we access an object type(not table of objects) in Oracle TABLE function? [message #611959 is a reply to message #611943] Thu, 10 April 2014 07:54 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Maybe using a pipelined function.

Re: How can we access an object type(not table of objects) in Oracle TABLE function? [message #611988 is a reply to message #611943] Thu, 10 April 2014 10:48 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3273
Registered: January 2010
Location: Connecticut, USA
Senior Member
Although object is a composite type it is still a scalar type, while TABLE operator works with collections. If you have just an object all you need is

v_select := 'SELECT t.o.a,t.o.b,t.o.c,t.o.d '
v_from := ' FROM (SELECT :1 o FROM dual) t ' 
v_where := '<where_predicate>'


For example:

SQL> desc emp_obj_type
 Name                                                                                      Null?    Type
 ----------------------------------------------------------------------------------------- -------- -------
 SAL                                                                                                NUMBER
 DEPTID                                                                                             NUMBER

SQL> set serveroutput on
SQL> declare
  2      v_sal number;
  3      v_deptid number;
  4  begin
  5      execute immediate 'select t.o.sal,t.o.deptid from (select :1 o from dual) t'
  6        into v_sal,v_deptid
  7        using emp_obj_type(9999,1);
  8      dbms_output.put_line('SAL = ' || v_sal || ' DEPTID = ' || v_deptid);
  9  end;
 10  /
SAL = 9999 DEPTID = 1

PL/SQL procedure successfully completed.

SQL> 


SY.
Re: How can we access an object type(not table of objects) in Oracle TABLE function? [message #611989 is a reply to message #611943] Thu, 10 April 2014 10:54 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3273
Registered: January 2010
Location: Connecticut, USA
Senior Member
But if you want to use TABLE, you need to declare object table type in SQL and use TABLE + MULTISET:

SQL> create or replace
  2    type emp_tbl_type
  3      as table of emp_obj_type
  4  /

Type created.

SQL> declare
  2      v_sal number;
  3      v_deptid number;
  4  begin
  5      execute immediate 'select * from table(
  6                                             cast(
  7                                                  multiset(
  8                                                           select :1 from dual
  9                                                          )
 10                                                  as emp_tbl_type
 11                                                 )
 12                                            )'
 13        into v_sal,v_deptid
 14        using emp_obj_type(9999,1);
 15      dbms_output.put_line('SAL = ' || v_sal || ' DEPTID = ' || v_deptid);
 16  end;
 17  /
SAL = 9999 DEPTID = 1

PL/SQL procedure successfully completed.

SQL> 


SY.
icon14.gif  Re: How can we access an object type(not table of objects) in Oracle TABLE function? [message #612017 is a reply to message #611989] Thu, 10 April 2014 22:47 Go to previous messageGo to next message
balaji.chelladurai
Messages: 6
Registered: April 2014
Junior Member
Great!! Thanks SY for your multiple solutions!
Re: How can we access an object type(not table of objects) in Oracle TABLE function? [message #612019 is a reply to message #611943] Fri, 11 April 2014 01:08 Go to previous message
vslabs
Messages: 26
Registered: March 2014
Location: Cape Town
Junior Member
The simplest approach is to construct a collection with the single variable object you have.

Basic example:
SQL> create or replace type TEmployee as object(
  2          id      integer,
  3          name    varchar2(10)
  4  );
  5  /

Type created.

SQL> 
SQL> 
SQL> create or replace type TEmployeeArray is table of TEmployee;
  2  /

Type created.

SQL> 
SQL> 
SQL> declare
  2          emp     TEmployee;
  3          name    varchar2(10);
  4  begin
  5          emp := new TEmployee(1,'jack');
  6  
  7          execute immediate
  8                  'select e.name from TABLE( TEmployeeArray(:1) ) e'
  9          into    name
 10          using   emp;
 11  
 12          dbms_output.put_line( 'name='||name );
 13  end;
 14  /
name=jack

PL/SQL procedure successfully completed.

SQL> 


Thus no need to pass a collection as a bind variable. Construct the collection in the SQL statement. Pass the object as the bind variable.
Previous Topic: oracle store procedure execution time takes too long
Next Topic: Taking a Snapshot
Goto Forum:
  


Current Time: Thu Apr 25 19:26:15 CDT 2024