Wednesday, October 14, 2009

Sort your nested table data.

Question: How do I sort data which is in a nested table.?

Answer: You might've enjoyed the power of set operations(MINUS,INTERSECT,UNION) in SQL many times.
For example - To combine to sets of data, to eliminate duplicated data among two sets etc.

How about using similar set operations in PL/SQL or Nested tables. ?
With Oracle 10g we can have Multiset operations on Nested tables.

Have you ever come accross a situation, where you need to sort data which is in a nested table.
Below is the sample code to sort nested table and then display it.
---

declare
-- I used one nested table type, which is already available(seeded) in APPS schema.
-- If required, create one table type as you reuired.

v_arr VARCHAR2_TABLE_200 := VARCHAR2_TABLE_200();

begin

v_arr:= VARCHAR2_TABLE_200 ('NEW YORK','SYDNEY', 'SINGAPORE','PERTH', 'NEW DELHI','',NULL,'LONDON');

            -- just print and see, how data is stored in nested table.
                dbms_output.put_line(chr(10)'Cities before sorting..'chr(10)'-----------------------');

for i in v_arr.first..v_arr.last
loop
         dbms_output.put_line(nvl(v_arr(i),'NULL'));

end loop ;

-- watch out NVL function above... wanted to show 'NULL' word, where ever there is NULL.
select cast(multiset(
select * from table(v_arr)
order by 1 asc NULLS FIRST) as VARCHAR2_TABLE_200)
into v_arr from dual;

-- NULLS FIRST in above statement is to display nulls first and then data. Default is nulls displayed last.
-- see if data is sorted or not...

dbms_output.put_line(chr(10)'Cities after sorting..'chr(10)'-----------------------');

for i in v_arr.first..v_arr.last
loop
          dbms_output.put_line(nvl(v_arr(i),'NULL'));
end loop ;
end ;
/

---- here's the output. -------

Cities before sorting..
-----------------------
NEW YORK
SYDNEY
SINGAPORE
PERTH
NEW DELHI
NULL
NULL
LONDON

Cities after sorting..
-----------------------
NULL
NULL
LONDON
NEW DELHI
NEW YORK
PERTH
SINGAPORE
SYDNEY

PL/SQL procedure successfully completed.
..

2 comments:

Kamesh Akundi said...

Hi,
I am trying to do the same but the Multiset function is not allowing to do so.

It throws ORA-22903: MULTISET expression not allowed.

Below is the code

Please help me out in debug the same
CREATE OR REPLACE FUNCTION SWAP_DIGITS(IN_NUMBER IN NUMBER) RETURN NUMBER IS
lnSwappedNumber NUMBER:=0;
TYPE SwapTable IS TABLE OF NUMBER NOT NULL;
ltSwappingTable SwapTable;
BEGIN
ltSwappingTable:=SwapTable();
ltSwappingTable.EXTEND(LENGTH(TO_CHAR(IN_NUMBER)));
FOR i IN 1..LENGTH(TO_CHAR(IN_NUMBER)) LOOP
ltSwappingTable(i):= TO_NUMBER(SUBSTR(TO_CHAR(IN_NUMBER),i,1));
DBMS_OUTPUT.PUT_LINE(ltSwappingTable(I));
END LOOP;

SELECT CASE(MULTISET(SELECT * FROM TABLE ltSwappingTable ORDER BY 1 ASC) AS SwapTable) INTO ltSwappingTable
FROM DUAL;

/*FOR j IN ltSwappedTable.first..ltSwappedTable.last LOOP
DBMS_OUTPUT.PUT_LINE(ltSwappedTable(j));
END LOOP;*/
RETURN lnSwappedNumber;
END;

Oracle Fusion procurement Training Institute said...
This comment has been removed by a blog administrator.