NOTE : This post is about splitting a single comma delimited string. If you have to apply it on a table with multiple rows having comma delimited strings, then look at Split comma delimited strings in a table using Oracle SQL
This is one of the most common questions in most of the Oracle SQL and PL/SQL forums. Although, there are several examples and demo over the web, I thought to summarize all the approaches together at one place.
- Regular expressions
- XML table
- MODEL clause
- Table function
- Pipelined function
Using REGULAR EXPRESSIONS
INSTR in CONNECT BY clause
SQL> WITH DATA AS
2 ( SELECT 'word1, word2, word3, word4, word5, word6' str FROM dual
3 )
4 SELECT trim(regexp_substr(str, '[^,]+', 1, LEVEL)) str
5 FROM DATA
6 CONNECT BY instr(str, ',', 1, LEVEL - 1) > 0
7 /
STR
----------------------------------------
word1
word2
word3
word4
word5
word6
6 rows selected.
SQL>
REGEXP_SUBSTR in CONNECT BY clause
SQL> WITH DATA AS
2 ( SELECT 'word1, word2, word3, word4, word5, word6' str FROM dual
3 )
4 SELECT trim(regexp_substr(str, '[^,]+', 1, LEVEL)) str
5 FROM DATA
6 CONNECT BY regexp_substr(str , '[^,]+', 1, LEVEL) IS NOT NULL
7 /
STR
----------------------------------------
word1
word2
word3
word4
word5
word6
6 rows selected.
SQL>
REGEXP_COUNT in CONNECT BY clause
SQL> WITH DATA AS
2 ( SELECT 'word1, word2, word3, word4, word5, word6' str FROM dual
3 )
4 SELECT trim(regexp_substr(str, '[^,]+', 1, LEVEL)) str
5 FROM DATA
6 CONNECT BY LEVEL <= regexp_count(str, ',')+1
7 /
STR
----------------------------------------
word1
word2
word3
word4
word5
word6
6 rows selected.
SQL>
Using XMLTABLE
SQL> WITH DATA AS
2 ( SELECT 'word1, word2, word3, word4, word5, word6' str FROM dual
3 )
4 SELECT trim(COLUMN_VALUE) str
5 FROM DATA, xmltable(('"' || REPLACE(str, ',', '","') || '"'))
6 /
STR
------------------------------------------------------------------------
word1
word2
word3
word4
word5
word6
6 rows selected.
SQL>
Using MODEL clause
SQL> WITH t AS
2 (
3 SELECT 'word1, word2, word3, word4, word5, word6' str
4 FROM dual ) ,
5 model_param AS
6 (
7 SELECT str orig_str ,
8 ','
9 || str
10 || ',' mod_str,
11 1 start_pos,
12 Length(str) end_pos,
13 (Length(str) - Length(Replace(str, ','))) + 1 element_count,
14 0 element_no,
15 ROWNUM rn
16 FROM t )
17 SELECT trim(Substr(mod_str, start_pos, end_pos-start_pos)) str
18 FROM (
19 SELECT *
20 FROM model_param MODEL PARTITION BY (rn, orig_str, mod_str)
21 DIMENSION BY (element_no)
22 MEASURES (start_pos, end_pos, element_count)
23 RULES ITERATE (2000)
24 UNTIL (ITERATION_NUMBER+1 = element_count[0])
25 (start_pos[ITERATION_NUMBER+1] = instr(cv(mod_str), ',', 1,
26 cv(element_no)) + 1,
27 end_pos[iteration_number+1] = instr(cv(mod_str), ',', 1,
28 cv(element_no) + 1) ) )
29 WHERE element_no != 0
30 ORDER BY mod_str ,
31 element_no
32 /
STR
------------------------------------------
word1
word2
word3
word4
word5
word6
6 rows selected.
SQL>
Using Table function
SQL> CREATE OR REPLACE TYPE test_type
2 AS
3 TABLE OF VARCHAR2(100)
4 /
Type created.
SQL> CREATE OR REPLACE
2 FUNCTION comma_to_table(
3 p_list IN VARCHAR2)
4 RETURN test_type
5 AS
6 l_string VARCHAR2(32767) := p_list || ',';
7 l_comma_index PLS_INTEGER;
8 l_index PLS_INTEGER := 1;
9 l_tab test_type := test_type();
10 BEGIN
11 LOOP
12 l_comma_index := INSTR(l_string, ',', l_index);
13 EXIT
14 WHEN l_comma_index = 0;
15 l_tab.EXTEND;
16 l_tab(l_tab.COUNT) := TRIM(SUBSTR(l_string,
17 l_index,
18 l_comma_index - l_index
19 )
20 );
21 l_index := l_comma_index + 1;
22 END LOOP;
23 RETURN l_tab;
24 END comma_to_table;
25 /
Function created.
SQL> sho err
No errors.
SQL> SELECT * FROM
2 TABLE(comma_to_table('word1, word2, word3, word4, word5, word6'))
3 /
COLUMN_VALUE
----------------------------------------------------------------------
word1
word2
word3
word4
word5
word6
6 rows selected.
SQL>
Using Pipelined Function
SQL> CREATE OR REPLACE TYPE test_type
2 AS
3 TABLE OF VARCHAR2(100)
4 /
Type created.
SQL> CREATE OR REPLACE
2 FUNCTION comma_to_table(
3 p_list IN VARCHAR2)
4 RETURN test_type PIPELINED
5 AS
6 l_string LONG := p_list || ',';
7 l_comma_index PLS_INTEGER;
8 l_index PLS_INTEGER := 1;
9 BEGIN
10 LOOP
11 l_comma_index := INSTR(l_string, ',', l_index);
12 EXIT
13 WHEN l_comma_index = 0;
14 PIPE ROW ( TRIM(SUBSTR(l_string,
15 l_index,
16 l_comma_index - l_index)));
17 l_index := l_comma_index + 1;
18 END LOOP;
19 RETURN;
20 END comma_to_table;
21 /
Function created.
SQL> sho err
No errors.
SQL> SELECT * FROM
2 TABLE(comma_to_table('word1, word2, word3, word4, word5, word6'))
3 /
COLUMN_VALUE
----------------------------------------------------------------------
word1
word2
word3
word4
word5
word6
6 rows selected.
SQL>
Hope it helps!
Filed under: Oracle Delimited String manipulation Tagged: comma delimited string, comma delimiter, comma separated string, split comma delimited string to rows, split string, sql split comma separated list of values Image may be NSFW.
Clik here to view.
Clik here to view.
Clik here to view.
Clik here to view.
Clik here to view.
Clik here to view.
Clik here to view.
Clik here to view.
