每天网上逛,总是想帮别人解决一点问题,但有的朋友没有给出明确的表,就给了一些样本数据,
于是要自己手动的WITH T AS (SELECT ... FROM DUAL UNION ALL ....)这样创建测试表,时间长了,感觉敲的好麻烦,我这个人比较懒,于是自己写了个自动创建测试表的存储。。。
create or replace procedure autocreate_withtable(pdata varchar2) --自动创建测试表 /*pdata varchar2(32000):='12,31 23,56 45,78';*/ as v_sql varchar2(32000); v_data varchar2(20000); v_TMP varchar2(20000); --v_char varchar2(5):='a'; l_idx INTEGER; TYPE fieldValueType IS TABLE OF VARCHAR2(500) INDEX BY BINARY_INTEGER; T_DATA fieldValueType; begin v_sql := 'with t as (' || CHR(10); v_data := pdata; loop l_idx := instr(v_data, CHR(10)); if l_idx > 0 then v_sql := v_sql || ' select '; v_TMP := substr(v_data, 1, l_idx - 1); SELECT * BULK COLLECT INTO T_DATA FROM TABLE(split_gw(v_TMP, ',')); for x in 1 .. T_DATA.count loop v_sql := v_sql || '''' || T_DATA(x) || ''' as a' || x || ','; end loop; v_sql := substr(v_sql, 1, length(v_sql) - 1); v_sql := v_sql || ' from dual ' || CHR(10) || 'union all' || CHR(10); v_data := substr(v_data, l_idx + 1); else v_sql := v_sql || ' select '; SELECT * BULK COLLECT INTO T_DATA FROM TABLE(split_gw(v_data, ',')); for x in 1 .. T_DATA.count loop v_sql := v_sql || '''' || T_DATA(x) || ''' as a' || x || ','; end loop; v_sql := substr(v_sql, 1, length(v_sql) - 1); v_sql := v_sql || ' from dual '; exit; end if; end loop; v_sql := v_sql || ')' || CHR(10) || 'SELECT * FROM T'; dbms_output.enable(40000); dbms_output.put_line(v_sql); end;
使用:(注意a,b,c后面都是回车,没有空格)
begin autocreate_withtable(pdata => 'date1,1,a date1,2,b date1,1,c date2,3,a date2,2,b date2,2,c'); end;
查看输出:
with t as (
select 'date1' as a1,'1' as a2,'a' as a3 from dual
union all
select 'date1' as a1,'2' as a2,'b' as a3 from dual
union all
select 'date1' as a1,'1' as a2,'c' as a3 from dual
union all
select 'date2' as a1,'3' as a2,'a' as a3 from dual
union all
select 'date2' as a1,'2' as a2,'b' as a3 from dual
union all
select 'date2' as a1,'2' as a2,'c' as a3 from dual )
SELECT * FROM T
----