需求:原始表的类型标签字段数据采用父子标签-拼接,多个标签,拼接。
如:tag1-subTag1,tag2,subTag5。
我们的目标标签字段应该为:tag1,tag2,其他类型。
数据库中有标签类型数据表tag_info,主要结构如下:
id | tag | parentId | lev |
---|
创建函数如下:
首先创建根据,拆分成数组的函数
create type tab_varchar is table of varchar2(255);
/**
功能:字符串分隔管道函数
p_str 源字符串
p_sep 分隔符,默认为逗号
*/
create or replace function get_split_str(p_str varchar2, p_sep varchar2 default ',')
return tab_varchar pipelined
is
l_idx int:=0;
v_list varchar2(4000) := p_str;
begin
loop
l_idx := instr(v_list,p_sep);
--没找到分隔符
if l_idx = 0 then
pipe row(v_list);
return;
--分隔符是第一个字符
elsif l_idx = 1 then
v_list := substr(v_list,l_idx+length(p_sep));
--分隔符是最后一个字符
elsif l_idx = length(v_list) then
pipe row(substr(v_list,1,l_idx-1));
return;
else
--打印第一个逗号之前的字符,然后继续执行
pipe row(substr(v_list,1,l_idx-1));
v_list := substr(v_list,l_idx+length(p_sep));
end if;
end loop;
end;
建立后创建下面的清洗函数
/**
洗涤标签函数;
negative 未经洗涤的标签字符串
步骤:1.先过剔除所有-后面的
2.匹配tag_info确定是否是一级标签如一级标签则保留否则替换成其他类型
*/
create function ysl_tag_wash(negative varchar2)
return varchar2 is res varchar2(4000);
cou number := 0;
var varchar2(4000) := '';
begin
--将参数按,分割;并遍历分割后的数组
for e in (select column_value from table(get_split_str(negative))) loop
--去除-后面的子级标签内容
var := case when instr(e.column_value,'-')=0 then e.column_value else substr(e.column_value,0,instr(e.column_value,'-')-1) end;
--判断该值是否在标签表中存在一级标签与之对应
select count(1) into cou from tag_info where tag = var and is_deleted = 0 and lev = 1 ;
--存在一级标签
if cou = 1
then
select tag into var from tag_info where tag = var and is_deleted = 0 and lev = 1 group by name;
else
--不存在则视为其他类型
var:='其他类型';
end if;
--重置cou变量
cou := 0;
if res is null
then
--首次拼接无需,
res:=res||var;
else
--不存在其他类型或当前标签不为其他类型则拼接
if instr(res,var)=0
then
res:=res||','||var;
end if;
end if;
end loop;
return res;
end;