String to Rows

Dynamic PL/SQL Method

This tutorial shows how to extract delimited values from a string like this

C
---------------
'v1','v2','v3'
 

and return them one value per row, like this.

  POSITION VAL
---------- ----------
         1 v1
         2 v2
         3 v3
 

The following dynamic PL/SQL¹ method works when the comma separated values are quoted character strings. Before proceeding though, let's look at our test data.

select * from t2 ;
 
KEY C               NOTE
--- --------------- -------------------------
r01 'v1'            One value
r02 'v1',''         Two values, one empty
r03 'v1','',''      Three values, two empty
r04 '','v2',''      Three values, two empty
r05 '','','v3'      Three values, two empty
r06 'v1','v2'       Two values
r07 'v1','v2',''    Three values, one empty
r08 'v1','v2','v3'  Three values, none empty
r09 ''              One empty value
r10 '',''           Two values, two empty
r11 '','',''        Three values, all empty
r12 (null)          NULL value
 

The first step is to create a function that converts a delimited string into a VARRAY of values.

create function csv_to_varray( p_string in varchar2 )
return
  varchar2_varray_type -- this type defined in Setup topic for this section
is
  v_table varchar2_varray_type ;
begin

  execute immediate
    'begin :v_table := varchar2_varray_type( ' || p_string || ' ); end;'
    using in out v_table
  ;

  return( v_table );

end;
/
 

The varray is then easily converted to a set of rows using a TABLE( ) collection expression.

set null     "(null)"
set pagesize 45

break on key skip 1 duplicates

select key, vt.column_value as val
from
  t2 ,
  table( csv_to_varray(t2.c) ) (+) vt
;
 
KEY VAL
--- ----------
r01 v1

r02 v1
r02 (null)

r03 v1
r03 (null)
r03 (null)

r04 (null)
r04 v2
r04 (null)

r05 (null)
r05 (null)
r05 v3

r06 v1
r06 v2

r07 v1
r07 v2
r07 (null)

r08 v1
r08 v2
r08 v3

r09 (null)

r10 (null)
r10 (null)

r11 (null)
r11 (null)
r11 (null)

r12 (null)
 

Numeric values

If the comma separated values are numbers like these

KEY C          NOTE
--- ---------- -------------------------
r01 1          One value

r02 1,2        Two values

r03 1,2,3      Three values

r04 (null)     NULL value
 

then the function must be modified to return a different varray type.

create function csv_num_to_varray( p_string in varchar2 )
return
  integer_varray_type -- this type defined in Setup topic for this section
is
  v_table integer_varray_type ;
begin

  execute immediate
    'begin :v_table := integer_varray_type( ' || p_string || ' ); end;'
    using in out v_table
  ;

  return( v_table );

end;
/
 

As before, the varray is then easily converted to a set of rows using a TABLE collection expression.

select key, vt.column_value as numeric_val
from
  t3 ,
  table( csv_num_to_varray(t3.c) ) (+) vt
;
 
KEY NUMERIC_VAL
--- -----------
r01           1

r02           1
r02           2

r03           1
r03           2
r03           3

r04 (null)
 

Gotchas

Note that both methods will produce errors if the delimited strings contain missing values, as in the strings " 'a',,'c' " and "1,,3".

select column_value as val
from   table( csv_num_to_varray( '1,,3' ) ) vt ;
from   table( csv_num_to_varray( '1,,3' ) ) vt
              *
ERROR at line 2:
ORA-06550: line 1, column 41:
PLS-00103: Encountered the symbol "," when expecting one of the following:
...
 

Warnings

  1. Dynamic SQL and Dynamic PL/SQL techniques can make your application vulnerable to SQL injection attacks. Use them with care or avoid their use altogether in sensitive applications.



Linking to SQL Snippets ™

To link to this page in Oracle Technology Network Forums or OraFAQ Forums cut and paste this code.

  • [url=http://www.sqlsnippets.com/en/topic-11714.html]SQL Snippets: String to Rows - Dynamic PL/SQL Method[/url]

To link to this page in HTML documents or Blogger comments cut and paste this code.

  • <a href="http://www.sqlsnippets.com/en/topic-11714.html">SQL Snippets: String to Rows - Dynamic PL/SQL Method</a>

To link to this page in other web sites use the following values.

  • Link Text : SQL Snippets: String to Rows - Dynamic PL/SQL Method
  • URL (href): http://www.sqlsnippets.com/en/topic-11714.html

Revision Notes

Date Category Note
2007-04-05 Revision This tutorial was moved from parent topic-11578.html to parent topic-12021.html.