oracle11g 拆分字符串的详细技巧
2016-11-18 10:30
183 查看
转自:http://m.blog.csdn.net/article/details?id=51946573
<-->功能需求
有一个比较长的SQL语句,查询出来中间会有类似“abc1,cbd2,db3,db5”这样的行记录,然后想要达到的效果就是将这样的记录按照逗号间隔符拆分出来一条变成4条,这样记录有多条,然后所有有逗号间隔符的都要拆分出来,然后形成新结果集去关联别的表记录。这条长的sql如下:select extractvalue(xmltype(r.approve_content), '/templet/content/nodeId') ids from res_approve_info t inner join res_approve_content r on t.res_approve_info_id=r.res_approve_info_id where t.auth_type_cd='JHGL_KFJH_10' and t.status_cd='2' and t.created_date >to_date('2016-01-01','yyyy-mm-dd') and extractvalue(xmltype(r.approve_content), '/templet/content/isOnTimeOrDelay')='2' |
1、思路分析
核心在于拆分字符串,拆分字符串sql参考先拆分然后再整合成一个临时表,拆分表达式已经想好了大概有如下2种方法:(1) 正则表达式的方式
(2) 存储函数的方式
2、正则表达式的实现方式
必须是oracle 10g+的版本才支持,以逗号间隔:SELECTREGEXP_SUBSTR ('abc1,cbd2,db3,db5', '[^,]+', 1,rownum)
FROM DUAL
CONNECTBYROWNUM <=
LENGTH ('abc1,cbd2,db3,db5') - LENGTH (REPLACE ('abc1,cbd2,db3,db5', ',', ''))+1;
执行如下:
SQL> SQL> SELECT REGEXP_SUBSTR ('abc1,cbd2,db3,db5', '[^,]+', 1,rownum) 2 FROM DUAL 3 CONNECTBYROWNUM <= 4 LENGTH ('abc1,cbd2,db3,db5') - LENGTH (REPLACE ('abc1,cbd2,db3,db5', ',', ''))+1; REGEXP_SUBSTR('ABC1,CBD2,DB3,D ---------------------------------- abc1 cbd2 db3 db5 SQL> |
3、以类型和函数的方式实现
(1)建立TYPE类型CREATEORREPLACETYPE str_split ISTABLEOFVARCHAR2 (4000) |
CREATEORREPLACEFUNCTION fun_splitstr(p_string INVARCHAR2, p_delimiter INVARCHAR2) RETURN str_split PIPELINED AS v_length NUMBER := LENGTH(p_string); v_start NUMBER := 1; v_index NUMBER; BEGIN WHILE(v_start <= v_length) LOOP v_index := INSTR(p_string, p_delimiter, v_start); IF v_index = 0 THEN PIPEROW(SUBSTR(p_string, v_start)); v_start := v_length + 1; ELSE PIPEROW(SUBSTR(p_string, v_start, v_index - v_start)); v_start := v_index + 1; ENDIF; ENDLOOP; RETURN; END fun_splitstr; |
SQL> select * fromtable(select fun_splitstr('abc1,cbd2,db3,db5',',') ids from dual)t1; COLUMN_VALUE -------------------------------------------------------------------------------- abc1 cbd2 db3 db5 SQL> |
4、效率比较高的办法
(1),在java代码(或者存储过程)里面循环遍历如下原始结果集,(2),通过拆分函数,按行循环来拆,把每一个拆出来的结果都插入到一个临时表或者临时集合t3里面,使用select * from table(fun_splitstr('aaa,bbb,ccc',','));来实现。
(3),最后你用这个临时集合去关联你需要关联的表就可以了
select t4.* from t3 left join plan6_node t4where t4.id=t3.id
5、效率比较低的办法(with临时表)
采用with临时表的办法来实现,sql如下,不过效率比较低:with temp0 as (selectLEVEL lv from dual CONNECTBYLEVEL <= 100) selectid,substr(t.vals,instr(t.vals, ',', 1, tv.lv) + 1, instr(t.vals, ',', 1, tv.lv + 1) -( instr(t.vals, ',', 1, tv.lv) + 1) ) ASname from (selectid,',' || name || ','AS vals, length(name || ',') - nvl(length(REPLACE(name, ',')), 0) AS cnt from (select1asid,'abc1,cbd2,db3,db5'asname from dual union allselect2, 'zhangsan1,lisi2,wanger3'from dual) ) t join temp0 tv on tv.lv <= t.cnt orderby1; |
SQL> with temp0 as (selectLEVEL lv from dual CONNECTBYLEVEL <= 100) 2 selectid,substr(t.vals,instr(t.vals, ',', 1, tv.lv) + 1, 3 instr(t.vals, ',', 1, tv.lv + 1) -( 4 instr(t.vals, ',', 1, tv.lv) + 1) 5 ) ASname 6 from (selectid,',' || name || ','AS vals, 7 length(name || ',') - nvl(length(REPLACE(name, ',')), 0) AS cnt 8 from (select1asid,'abc1,cbd2,db3,db5'asname from dual union allselect2, 'zhangsan1,lisi2,wanger3'from dual) 9 ) t join temp0 tv 10 on tv.lv <= t.cnt orderby1; IDNAME ---------- -------------------------------------------------- 1 abc1 1 db3 1 cbd2 1 db5 2 wanger3 2 zhangsan1 2 lisi2 7rows selected SQL> |
临时解决办法是,createtable z_temp2 asselect1asid,'abc1,cbd2,db3,db5'asname from dual union allselect2, 'zhangsan1,lisi2,wanger3'from dual;然后连接这个temp1表进行操作,那么总体sql如下:
createtable z_temp2 asselect1asid,'abc1,cbd2,db3,db5'asname from dual union allselect2, 'zhangsan1,lisi2,wanger3'from dual; with temp0 as (selectLEVEL lv from dual CONNECTBYLEVEL <= 100) selectid,substr(t.vals,instr(t.vals, ',', 1, tv.lv) + 1, instr(t.vals, ',', 1, tv.lv + 1) -( instr(t.vals, ',', 1, tv.lv) + 1) ) ASname from (selectid,',' || name || ','AS vals, length(name || ',') - nvl(length(REPLACE(name, ',')), 0) AS cnt from z_temp2 ) t join temp0 tv on tv.lv <= t.cnt orderby1; |
参考文档:http://www.anbob.com/archives/221.html
相关文章推荐
- oracle11g 拆分字符串的详细技巧
- T-SQL技巧收集——拆分字符串
- T-SQL技巧收集——拆分字符串
- T-SQL技巧收集——拆分字符串
- 数据库技巧汇总——拆分字符串
- 【C++编程技巧】根据字符串中的指定字符作为分界将字符串拆分
- T-SQL技巧收集——拆分字符串
- linux命令之目录监控 字符串拆分 监控命令运行结果 统计行数 去除文本头尾空格 获取网卡名浮点数运算等命令使用技巧
- 拆分字符串,并存入临时表中
- SQL 拆分字符串的经典方法
- [转]详细了解杀毒技巧
- 请问如果我有字符串 “300,500,600-700”用JAVASCRIPT怎样才能拆分这个字符串,取得数字300 500 600 和700
- 关于GridView的两个技巧(格式字符串和隐藏列)
- 字符串、汉字的拆分问题的解法
- 深入聊聊Array的sort方法的使用技巧.详细点评protype.js中的sortBy方法
- asp拆分字符串
- 经典的拆分字符串的语句
- 将表某个字符串拆分生成多行数据[经典]
- 妙用 T-SQL: PARSENAME 函数 (也可不使用该函数,鸣谢"小杰") 实现按指定分隔符拆分字符串 SplitString
- 拆分字符串的SQL数据库函数