Search code examples
sqloracle-databaseplsqljdeveloper

Selecting from a column of nested tables SQL


I have a question on how to print all the values of an object of a defined type. I have an table SP of objects of type PROJECTT. When I query a row in SP for its object(s), it returns the type of the object (PROJECTT) but not the contents of the object. The type PROJECTT has 5 varchar columns, which is what I want returned.

Below are is my SQL for my table and type

set echo on
set serveroutput on

drop table ACTIVES;
drop table POBJECT;
drop type ACTIVEST;
drop type POBJECTT;


create type POBJECTT as
   object (p# varchar(5), pname varchar(20), color varchar(10),
           weight number, city varchar(10));

create table POBJECT of POBJECTT;
   insert into POBJECT(p#, pname, color, weight, city) values
    ('P1', 'Nut', 'Red', 12, 'London');
   insert into POBJECT(p#, pname, color, weight, city) values
   ('P2', 'Bolt', 'Green', 17, 'Paris');
   insert into POBJECT(p#, pname, color, weight, city) values
   ('P3', 'Screw', 'Blue', 17, 'Rome');
   insert into POBJECT(p#, pname, color, weight, city) values
   ('P4', 'Screw', 'Red', 14, 'London');
   insert into POBJECT(p#, pname, color, weight, city) values
   ('P5', 'Cam', 'Blue', 12, 'Paris');
   insert into POBJECT(p#, pname, color, weight, city) values
   ('P6', 'Cog', 'Red', 19, 'London');

  create type ACTIVEST as table of ref POBJECTT;
   /

  create table ACTIVES(s# varchar(5), sname varchar(20), status number, 
                     city varchar(10), sp ACTIVEST)

Then using a Java SAX parser and XML file, I fill the sp column of ACTIVES with references to rows in the POBJECTS table.

I am trying to print these rows using a select statement. I am not quite sure how to get the values of the object in SP, so I started with something like:

select * from (select sp from actives where S# = 'S1')

Solution

  • select
        deref(column_value).p# p#
        ,deref(column_value).pname pname
        ,deref(column_value).color color
        ,deref(column_value).weight weight
        ,deref(column_value).city city
    from actives cross join table(sp)
    where s# = 'S1';
    
    P#    PNAME                COLOR          WEIGHT CITY
    ----- -------------------- ---------- ---------- ----------
    P1    Nut                  Red                12 London
    P2    Bolt                 Green              17 Paris
    
    SQL>
    

    Assuming you ran an insert like this before:

    insert into actives
    select 'S1', 'sname', 0, 'city'
        ,activest(
            (select ref(p) from pobject p where p# = 'P1')
            ,(select ref(p) from pobject p where p# = 'P2')
        )
    from dual;
    

    Also, your ACTIVES DDL didn't work for me. I had to add nested table sp store as sp_tab; to the end of it.