免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2644 | 回复: 0
打印 上一主题 下一主题

[分享] [个人小结]浅谈sql的字符分割 [复制链接]

论坛徽章:
7
亥猪
日期:2013-10-10 17:00:29辰龙
日期:2013-10-12 16:23:19卯兔
日期:2013-11-18 17:01:27金牛座
日期:2014-09-09 10:17:052015七夕节徽章
日期:2015-08-21 11:06:172015亚冠之柏太阳神
日期:2015-09-25 13:56:42数据库技术版块每日发帖之星
日期:2016-08-06 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-07-21 17:17 |只看该作者 |倒序浏览
对于oracle;在字符串处理时;经常会遇到字符串分割的问题;可惜SQL中没有split函数;这个倒是挺困扰我们写sql的。对此;我来说说这字符串分割。

  例如对字段str中一条数据是'120-mm-265';我要取到其中的mm。若对其它语言之间;例如awk。split("120-mm-265",a,"-");print a[2];就搞定了。

  1. 可能大家觉得很简单;我用substr(str,5,2)就行了。可惜你把问题想得太简单了。我们处理是多条数据;而不是一条数据。若它下面一条的数据是'12-oko-45'。这样的话 。那就是ko;并非我们想要的oko

  2. 可能大家还会想到instr函数。这个函数是可以解决的。但是还是要借用sbustr函数
  1. SELECT substr('120-mm-265',
  2.                 instr('120-mm-265', '-', 1, 1) + 1,
  3.                 instr('120-mm-265', '-', 1, 2) -
  4.                 (instr('120-mm-265', '-', 1, 1) + 1))
  5. FROM   dual
复制代码
这样的结果大家可以接受吗?

  3. 两年前;我想到一种方法。就是借用ltrim,rtrim函数。由于前面和后面都是数字
  1. SELECT rtrim(ltrim('120-mm-265', '0123456789-'), '0123456789-')
  2. FROM   dual;
复制代码
这种情况是可以实现。但是这种情况呢'20m-mm-f25'。这种实现扩展性不强。所以这种也不考虑。

  4. 由于上面3种写法;大家能接受吗?不能接受;那就进入高级写法。
   使用正则函数。
  1. SELECT regexp_substr('120-mm-265', '[^-]+', 1, 2)
  2. FROM   dual;   --推荐这种。

  3. SELECT regexp_replace('120-mm-265', '(.*)-(.*)-(.*)', '\2')
  4. FROM   dual;
复制代码
我相信这两种方法应该可以让你满意;若还不能让你满意;那就是正则函数是10g版本才有的。若低于10g版本,那该怎么办?那就看看下面吧
5. 自定义函数split。oracle不提供内置函数split。那么就自定义。
  1. CREATE OR REPLACE FUNCTION split
  2. (
  3.     v_desc  IN   VARCHAR,
  4.     v_icount IN NUMBER
  5. ) RETURN VARCHAR IS
  6.     v_result  VARCHAR(20);
  7.     v_pos     NUMBER(2);
  8.     v_str     VARCHAR(1000);
  9.     v_count_2 NUMBER(2);
  10.     v_word    VARCHAR(20);
  11. BEGIN
  12.     v_result  := '';
  13.     v_str     := v_desc || ',,,';
  14.     v_count_2 := 0;
  15.     v_pos     := instr(v_str, ',');
  16.     WHILE v_pos > 1
  17.     LOOP
  18.         v_count_2 := v_count_2 + 1;
  19.         v_word    := substr(v_str, 1, v_pos - 1);
  20.         IF v_icount = v_count_2 THEN
  21.             v_result := v_word;
  22.             RETURN v_result;
  23.         ELSE
  24.             IF v_icount < v_count_2 THEN
  25.                 RETURN '';
  26.             ELSE
  27.                 IF v_str <> ',' THEN
  28.                     v_str := substr(v_str, v_pos + 1);
  29.                     v_pos := instr(v_str, ',');
  30.                 END IF;
  31.             END IF;
  32.         END IF;
  33.     END LOOP;
  34.     RETURN v_result;
  35. END;
复制代码
以上是个人小结;刚刚看到几个字符串分割的题目;才有意提供下。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP