【原创】管道函数在代码翻译中的应用

有这样一条sql:

select c_lx from t_table where n_id=1;

 查询结果为:

1;2;3;4;5;6;

 有没有这样一个函数,将该记录以‘;’切分并转换为多行的结果集,如:

1

2

3

4

5

6

 注意:是结果集(6行),而不是一条纵向显示的记录。
我知道oracle有wm_concat函数,可以将多条记录合并成一条,并以逗号分割。

使用场景:
如代码类型,控件保存时是以‘5;6;7;8;9;10;’的格式保存在一个字段里的,一般对应的代码名称都会冗余一列,如‘工人;农民;干部;’,但是很多地方并没有冗余,在展示的时候,翻译代码时便出现了麻烦,所以如果存在一个函数,将该代码值切分并以多条结果集返回,那么一个表连接即可将代码翻译,如:
select c_mc from t_dm where n_dm in(select xxx from xxx) and n_id=xxx;
不知道有没有这样的一个函数?在搜索之后我没有找到,无奈自己实现了一个:
创建类型:

create or replace type type_dm as object

(

  DM number(5)

);



create or replace type list_dm as table of type_dm;

 函数定义:

create or replace function FN_ROW2Column(c_tag varchar) return list_dm

  pipelined as

  v_type_dm type_dm;

  c_tmp     number(3);

  c_middle  varchar(50);



begin

  c_middle := c_tag;

  loop

    c_tmp     := substr(c_middle, 1, instr(c_middle, ';') - 1);

    c_middle  := substr(c_middle,

                        instr(c_middle, ';') + 1,

                        length(c_middle));

    v_type_dm := type_dm(c_tmp);

    pipe row(v_type_dm);

    exit when c_middle is null;

  end loop;

  return;

end FN_ROW2Column;

 测试:

select * from table(FN_ROW2Column('1;23;2;12;5;4;5;5;6;5;5;4;'))

1

23

2

12

5

4

5

5

6

5

5

4

 那么在翻译代码时:

select wm_concat(c_mc) from t_dm where n_dm in(select * from table(FN_ROW2Column('1;23;2;12;5;4;5;5;6;5;5;4;'))) and n_id=xxx;

 这样一个sql即可完美的将复杂代码翻译完,就是不知道有没有一个内置函数有这样的功能。

加强版的:

--c_tag:要解析的目标字符串,如1;2;3;4

--tag:分隔标记,代表字符串之间的分隔符,如;,默认为';'

create or replace function FN_ROW2Column(c_tag varchar,

                                         tag   varchar default ';')

  return list_dm

  pipelined as

  v_type_dm type_dm;

  c_tmp     number(3);

  c_middle  varchar(50);



begin

  c_middle := c_tag;

  loop

    if substr(c_middle, length(c_middle)) != tag then

      c_middle := c_middle || tag;

    end if;

    c_tmp     := substr(c_middle, 1, instr(c_middle, tag) - 1);

    c_middle  := substr(c_middle,

                        instr(c_middle, tag) + 1,

                        length(c_middle));

    v_type_dm := type_dm(c_tmp);

    pipe row(v_type_dm);

    exit when c_middle is null;

  end loop;

exception

  when others then

    --出现异常,静默不予处理

   -- do nothing;

    return;

end FN_ROW2Column;

 

你可能感兴趣的:(函数)