This article show how to translate string separated by a character
'STR1,STR2,STR3,STR4'
into rows
STR_REC ------------------- STR1 STR2 STR3 STR4
CONNECT BY
This method uses regular expressions and CONNECT BY. Nice but can be hard for read and use
SELECT regexp_substr('STR1,STR2,STR3,STR4','[^,]+', 1, level) str_rec FROM dual CONNECT BY LEVEL <= (1+regexp_count('STR1,STR2,STR3,STR4', ',')); STR_REC ------------------- STR1 STR2 STR3 STR4
COLLECTION
Almost the same as above but I have wrapped it in function to simplify sql statements
CREATE OR REPLACE TYPE t_agg_rec AS OBJECT ( str_rec CLOB ) / CREATE OR REPLACE TYPE t_agg_tbl FORCE AS TABLE OF t_agg_rec; / CREATE OR REPLACE FUNCTION FN_SPLIT_CONVERTED ( in_str IN CLOB, in_del IN VARCHAR2 ) RETURN t_agg_tbl PIPELINED AS BEGIN FOR i IN ( SELECT regexp_substr(in_str,'[^'||in_del||']+', 1, level) str_rec FROM dual CONNECT BY LEVEL <= (1+regexp_count(in_str,in_del))) LOOP PIPE ROW(t_agg_rec(i.str_rec)); END LOOP; RETURN; END FN_SPLIT_CONVERTED; SELECT * FROM TABLE(fn_split_converted('STR1,STR2,STR3,STR4', ',')); STR_REC ---------- STR1 STR2 STR3 STR4
So it can be easy used in subqueries with IN clause
SELECT * FROM <TABLE_NAME> WHERE <COLUMN_ID> IN (SELECT * FROM TABLE(fn_split_converted('STR1,STR2,STR3,STR4', ','))
XML
Another option using xmltable method
SELECT (COLUMN_VALUE).getClobVal() str_rec FROM xmltable ( ('"'||REPLACE('STR1,STR2,STR3,STR4', ',', '","')||'"') ); STR_REC ------------------- STR1 STR2 STR3 STR4
I believe that world as you know it is easier now ;o)
Have a fun 🙂
Tomasz
Great, short and comprehensive article.
From my side, I would add an implementation of function without SELECT statement and without REGEXP, as SELECT + REGEXP is much slower than pure PL/SQL processing.
We could also use XMLTABLE approach:
SQL> select column_value
2 from xmltable((‘”‘||replace(‘STR1,STR2,STR3,STR4’, ‘,’, ‘”,”‘)||'”‘));
COLUMN_VALUE
—————————————————————————–
STR1
STR2
STR3
STR4
Very nice I like it 🙂
Regards
Tomasz