create procedure cols2rows( in p_sel_stmt clob(2m) , in p_collen int , in p_vallen int , out p_rc int , out p_msg varchar(128) , out p_stmt clob(2m) ) LANGUAGE SQL DYNAMIC RESULT SETS 1 BEGIN declare SQLCODE int; declare l_SQLTYPE_ID int; declare l_SQLTYPE varchar(128); declare l_SQLLENGTH int; declare l_SQLSCALE int; declare l_SQLNAME_DATA varchar(128); declare l_SQLTYPEF varchar(128); declare l_colexpr clob(2m) default ''; declare l_valexpr clob(2m) default ''; declare l_colid int default 0; declare l_collen varchar(10); declare l_vallen varchar(10); declare l_colname varchar(128); declare l1 RESULT_set_LOCATOR VARYING; declare c_out cursor with return for s_out; declare EXIT HANDLER FOR SQLEXCEPTION BEGIN GET DIAGNOSTICS EXCEPTION 1 p_msg = MESSAGE_TEXT; set p_rc = SQLCODE; END; set l_collen=trim(char(coalesce(p_collen, 10))), l_vallen=trim(char(coalesce(p_vallen, 80))); -- construct case clauses set p_stmt = 'describe '||p_sel_stmt; set l_colexpr = 'when 0 then cast(repeat(''-'', '||l_collen||') as char('||l_collen||'))'; set l_valexpr = 'when 0 then cast(repeat(''-'', '||l_vallen||') as char('||l_vallen||'))'; call SYSPROC.ADMIN_CMD(p_stmt); associate result set locator (l1) with procedure SYSPROC.ADMIN_CMD; allocate c1 cursor for result set l1; open c1; fetch c1 into l_SQLTYPE_ID, l_SQLTYPE, l_SQLLENGTH, l_SQLSCALE, l_SQLNAME_DATA; while (SQLCODE!=100) do set l_colid = l_colid+1; set l_colname = case l_SQLTYPE_ID when 404 -- BLOB then '''x''''''||hex(a.'||l_SQLNAME_DATA||')||''''''''' when 988 -- XML then 'xmlserialize(a.'||l_SQLNAME_DATA||' as clob(4000))' else 'a.'||l_SQLNAME_DATA end; set l_colexpr=l_colexpr||' '||'when '||rtrim(char(l_colid))||' then cast('''||l_SQLNAME_DATA||''' as char('||l_collen||'))'; set l_valexpr=l_valexpr||' '||'when '||rtrim(char(l_colid))||' then cast('||l_colname||' as char('||l_vallen||'))'; fetch c1 into l_SQLTYPE_ID, l_SQLTYPE, l_SQLLENGTH, l_SQLSCALE, l_SQLNAME_DATA; end while; close c1; -- construct select statement set p_stmt= 'with ' ||' a as (select s.*, rownumber() over() rn_ from ('||p_sel_stmt||') s) ' ||', t (i) as (values 0 union all select i+1 from t where i<'||trim(char(l_colid))||') ' ||'select ' ||' case t.i '||l_colexpr||' end as col ' ||', case t.i '||l_valexpr||' end as val ' ||'from a, t ' ||'order by a.rn_, t.i'; -- execute this statement prepare s_out from p_stmt; open c_out; set p_rc=0; END@ call cols2rows('select * from table(values (current date, current time, current timestamp, double(1), real(1), 1, dec(1), clob(''123''), blob(''123''), decfloat(1), xmlparse (document ''1'')) , (current date, current time, current timestamp, double(2), real(2), 2, dec(2), clob(''456''), blob(''456''), decfloat(2), xmlparse (document ''2'')) ) t(dt, tm, ts, dbl, rl, i, dec, cl, bl, df, xl)', 10, 80, ?, ?, ?)@ call cols2rows('select PRIV_WORKSPACE_SECTION_LOOKUPS PRIV_WORKSPACE_SECTION_LOOKUP, AGENT_ID from sysibmadm.snapappl fetch first 2 rows only', 50, 50, ?, ?, ?)@