Comments on: Sorting PL/SQL Collections, the quite simple way (part two: Have the SQL Engine do the heavy lifting) https://technology.amis.nl/2006/05/31/sorting-plsql-collections-the-quite-simple-way-part-two-have-the-sql-engine-do-the-heavy-lifting/ Friends of Oracle and Java Thu, 21 May 2015 20:49:51 +0000 hourly 1 http://wordpress.org/?v=4.2.2 By: Janos Ujvari https://technology.amis.nl/2006/05/31/sorting-plsql-collections-the-quite-simple-way-part-two-have-the-sql-engine-do-the-heavy-lifting/#comment-3370 Fri, 30 Sep 2011 09:32:24 +0000 http://technology.amis.nl/blog/?p=1217#comment-3370 Great post
thank you very much.

]]>
By: shab https://technology.amis.nl/2006/05/31/sorting-plsql-collections-the-quite-simple-way-part-two-have-the-sql-engine-do-the-heavy-lifting/#comment-3369 Wed, 24 Aug 2011 03:04:12 +0000 http://technology.amis.nl/blog/?p=1217#comment-3369 Hi Lucas
Great article and examples -thanks.
One issue though, I got his working for my needs on a relatively small dataset but when I tried to scale it up to sort a pl/sql table of around 4 million rows I received the following error:
ORA-22813: operand value exceeds system limits
This error arises on the following statement.
select cast(multiset(select t_pair
(actual,
predicted,
original_index)
from table(l_tbl)
order by predicted desc, original_index asc) as t_pairs)
into l_tbl
from dual;
I know that you said that you hadn’t tested it with a large data set, I guess i just did.   Any suggestions on to sorting larger pl/sql tables?
Thanks
shab

]]>
By: Trout https://technology.amis.nl/2006/05/31/sorting-plsql-collections-the-quite-simple-way-part-two-have-the-sql-engine-do-the-heavy-lifting/#comment-3368 Fri, 14 May 2010 14:24:16 +0000 http://technology.amis.nl/blog/?p=1217#comment-3368 Combining this with analytical functions is very useful.  I am using the technique in a modeling package that uses bulk inserts to speed the processing of large volumes of rows (35 million).  By using this method I can get the analytical function results without having to go to the DB a second time for updates after the inital inserts.

]]>
By: Trout https://technology.amis.nl/2006/05/31/sorting-plsql-collections-the-quite-simple-way-part-two-have-the-sql-engine-do-the-heavy-lifting/#comment-3367 Wed, 28 Apr 2010 19:43:12 +0000 http://technology.amis.nl/blog/?p=1217#comment-3367 Thanks for this.  Saved me a fair bit of time.

]]>
By: Thaha https://technology.amis.nl/2006/05/31/sorting-plsql-collections-the-quite-simple-way-part-two-have-the-sql-engine-do-the-heavy-lifting/#comment-3366 Mon, 12 Oct 2009 13:56:41 +0000 http://technology.amis.nl/blog/?p=1217#comment-3366 Wonderful example.. Thanks a lot …

]]>
By: Daniel https://technology.amis.nl/2006/05/31/sorting-plsql-collections-the-quite-simple-way-part-two-have-the-sql-engine-do-the-heavy-lifting/#comment-3365 Fri, 24 Oct 2008 18:07:48 +0000 http://technology.amis.nl/blog/?p=1217#comment-3365 Thanks for your simple collection sorting method. I have been looking for a way to do this without relying on an index.

It’s so hard to find clear solutions for what should be simple Oracle tasks. No wonder I usually do things like this on the Java application side.

]]>
By: M.Bilal https://technology.amis.nl/2006/05/31/sorting-plsql-collections-the-quite-simple-way-part-two-have-the-sql-engine-do-the-heavy-lifting/#comment-3364 Tue, 27 Feb 2007 14:59:34 +0000 http://technology.amis.nl/blog/?p=1217#comment-3364 It is really great, and lot of thanks for this article.

]]>
By: Patrick Sinke https://technology.amis.nl/2006/05/31/sorting-plsql-collections-the-quite-simple-way-part-two-have-the-sql-engine-do-the-heavy-lifting/#comment-3363 Sun, 27 Aug 2006 13:27:14 +0000 http://technology.amis.nl/blog/?p=1217#comment-3363 I also encountered a way to do it without the necessity to create a type outside the package (which is annoying):

DECLARE
TYPE typ_sorttabIS TABLE OF NUMBER(1) index by VARCHAR2(100) ;
l_order_tab typ_sorttab;
ln_pos NUMBER(8) ;
lv_input VARCHAR2(100) ;
lv_input_string varchar2(100) ;
lb_doorgaan boolean default TRUE;
lv_result VARCHAR2(100) := ‘;'; — string begint met een ‘;’
BEGIN
lv_input_string := ‘;BLA;DIE;BLOE;TEST;’
— 1e gedeelte leest de inputstring in een array
ln_pos := instr(lv_input_string, ‘;’);
WHILE lb_doorgaan
LOOP
lv_input := substr(lv_input_string, 1, ln_pos-1) ; — alles tot eerstvolgende scheidingsteken
IF lv_input is not null
THEN
— deze controle is nodig omdat de eerste keer een lege string zal opleveren
l_order_tab(lv_input) := 1 ;
END IF;
lv_input_string := substr(lv_input_string, ln_pos + 1) ; — input_string min input
ln_pos := instr(lv_input_string, ‘;’) ;– volgende scheidingsteken
lb_doorgaan := ln_pos > 0 ; — scheidingstekens nog aanwezig
END LOOP ;
— 2e gedeelte voor output
lv_input := l_order_tab.first ;
WHILE lv_input IS NOT NULL
LOOP
lv_result := lv_result || lv_input || ‘;’ ;
lv_input := l_order_tab.next(lv_input) ;
END LOOP ;

end;

The trick is too create a table of number with index on the field to be sorted. In this example the array is filled manually from a comma-separated string and sorted by looping through the array in order of index.

]]>
By: Kate Johnson https://technology.amis.nl/2006/05/31/sorting-plsql-collections-the-quite-simple-way-part-two-have-the-sql-engine-do-the-heavy-lifting/#comment-3362 Wed, 23 Aug 2006 23:40:52 +0000 http://technology.amis.nl/blog/?p=1217#comment-3362 Thank you so much for this article, I have been hunting for how to properly use TABLE/CAST and now you made it even easier with TABLE/CAST/MULTISET. Thank you very much. 2 days of searching is now over.

Next, INSERT/UPDATE/DELETE examples….

]]>
By: Francois https://technology.amis.nl/2006/05/31/sorting-plsql-collections-the-quite-simple-way-part-two-have-the-sql-engine-do-the-heavy-lifting/#comment-3361 Wed, 31 May 2006 12:32:43 +0000 http://technology.amis.nl/blog/?p=1217#comment-3361 Great !
Another solution to sort a collection of records by using the . (dot) notation:

create or replace TYPE typ_emp_rec AS OBJECT( empno NUMBER(4), ENAME VARCHAR(10) )
/

create or replace TYPE typ_tab_emp_rec AS TABLE OF typ_emp_rec
/

SQL> declare
2 tremp typ_tab_emp_rec := typ_tab_emp_rec( null);
3 tremp2 typ_tab_emp_rec := typ_tab_emp_rec( null);
4 nb pls_integer := 0 ;
5 begin
6
7 tremp.extend(5) ;
8 for i In reverse 1..5 loop
9 nb := nb + 1 ;
10 tremp(nb) := new typ_emp_rec(i, ‘Name’ || to_char(i) ) ;
11 end loop ;
12
13 — output the collection non-sorted —
14 dbms_output.put_line( ‘*** non-sorted collection ***’ ) ;
15 for i In tremp.first .. tremp.last loop
16 dbms_output.put_line( tremp(i).ename ) ;
17 end loop ;
18
19 select cast ( multiset( select t.*
20 from table( tremp ) t
21 order by t.ename
22 ) as typ_tab_emp_rec)
23 into tremp2
24 from dual;
25 — output the collection sorted on ename —
26 dbms_output.put_line( ‘*** sorted collection (field 2) ***’ ) ;
27 for i In tremp2.first .. tremp2.last loop
28 dbms_output.put_line( tremp2(i).ename ) ;
29 end loop ;
30 end ;
31
32 /
*** non-sorted collection ***
Name5
Name4
Name3
Name2
Name1
*** sorted collection (field 2) ***
Name1
Name2
Name3
Name4
Name5

Procédure PL/SQL terminée avec succès.

]]>