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

有这样一条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;
原文地址:https://www.cnblogs.com/zhangxsh/p/3499470.html