zoukankan      html  css  js  c++  java
  • 浅谈sql的字符分割

       对于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函数

    SELECT substr('120-mm-265',
    				instr('120-mm-265', '-', 1, 1) + 1,
    				instr('120-mm-265', '-', 1, 2) -
    				(instr('120-mm-265', '-', 1, 1) + 1))
     FROM   dual
    

      这样的结果大家可以接受吗?

      3. 两年前;我想到一种方法。就是借用ltrim,rtrim函数。由于前面和后面都是数字

    SELECT rtrim(ltrim('120-mm-265', '0123456789-'), '0123456789-')
    FROM   dual;
    

      这种情况是可以实现。但是这种情况呢'20m-mm-f25'。这种实现扩展性不强。所以这种也不考虑。

      4. 由于上面3种写法;大家能接受吗?不能接受;那就进入高级写法。
       使用正则函数。

           SELECT regexp_substr('120-mm-265', '[^-]+', 1, 2)
           FROM   dual;   --推荐这种。
       
           SELECT regexp_replace('120-mm-265', '(.*)-(.*)-(.*)', '2')
           FROM   dual;
    

     我相信这两种方法应该可以让你满意;若还不能让你满意;那就是正则函数是10g版本才有的。若低于10g版本,那该怎么办?那就看看下面吧

      5. 自定义函数split。oracle不提供内置函数split。那么就自定义。

    CREATE OR REPLACE FUNCTION splitstr
    (
        v_desc  IN   VARCHAR,
        v_icount IN NUMBER
    ) RETURN VARCHAR IS
        v_result  VARCHAR(20);
        v_pos     NUMBER(2);
        v_str     VARCHAR(1000);
        v_count_2 NUMBER(2);
        v_word    VARCHAR(20);
    BEGIN
        v_result  := '';
        v_str     := v_desc || ',,,';
        v_count_2 := 0;
        v_pos     := instr(v_str, ',');
        WHILE v_pos > 1
        LOOP
            v_count_2 := v_count_2 + 1;
            v_word    := substr(v_str, 1, v_pos - 1);
            IF v_icount = v_count_2 THEN
                v_result := v_word;
                RETURN v_result;
            ELSE
                IF v_icount < v_count_2 THEN
                    RETURN '';
                ELSE
                    IF v_str <> ',' THEN
                        v_str := substr(v_str, v_pos + 1);
                        v_pos := instr(v_str, ',');
                    END IF;
                END IF;
            END IF;
        END LOOP;
        RETURN v_result;
    END;
    

      SELECT splitstr(replace('120-mm-265','-',','),2) from dual
        这样执行就ok
       若还有好点的方法到时候再补充;若大家有好点的方法也可以补充。

  • 相关阅读:
    SpringMVC使用ResponseEntity实现文件下载,及图片base64的字节数组上传于下载
    File类的createNewFile()和mkdirs() mkdir()
    为什么Java里的Arrays.asList不能用add和remove方法?
    java如何向数组里添加元素
    java里getPath、 getAbsolutePath、getCanonicalPath的区别
    MultipartFile 类
    File类的createNewFile()与createTempFile()的区别
    IntelliJ Idea解决Could not autowire. No beans of 'xxxx' type found的错误提示
    FileInputStream读取的两种方法:逐字节读;以字节数组读取
    JCE cannot authenticate the provider BC
  • 原文地址:https://www.cnblogs.com/lottu/p/4013751.html
Copyright © 2011-2022 走看看