oracle split去逗号,行列转换

转载

1.针对  '1','2','3','4','5'(逗号在字符串外面)

 

  1. SQL> SELECT COLUMN_VALUE  FROM TABLE(SYS.ODCIVARCHAR2LIST('1','2','3','4','5'));  
  2.   
  3. COLUMN_VALUE  
  4. --------------------------------------------------------------------------------  
  5. 1  
  6. 2  
  7. 3  
  8. 4  
  9. 5  


2.针对'1,2,3,4,5'(逗号在字符串里面)

 

  1. SQL> select regexp_substr('1,2,3,4,5','[^,]+',1,rownum) from dual  
  2.   2  connect by rownum<=length('1,2,3,4,5')-length(replace('1,2,3,4,5',','))+1  
  3.   3  ;  
  4.   
  5. REGEXP_SUBSTR('1,2,3,4,5','[^,  
  6. ------------------------------  
  7. 1  
  8. 2  
  9. 3  
  10. 4  
  11. 5  


3.使用函数

 

  1. CREATE OR REPLACE TYPE ty_str_split IS TABLE OF VARCHAR2 (4000);  

 

 

  1. CREATE OR REPLACE FUNCTION fn_split (p_str IN CLOB, p_delimiter IN VARCHAR2)  
  2.  RETURN ty_str_split  
  3. IS  
  4.   j INT := 0;  
  5.   i INT := 1;  
  6.   len INT := 0;  
  7.   len1 INT := 0;  
  8.   str VARCHAR2 (4000);  
  9.   str_split ty_str_split := ty_str_split ();  
  10. BEGIN  
  11.   len := LENGTH (p_str);  
  12.   len1 := LENGTH (p_delimiter);  
  13.   
  14.   WHILE j < len  
  15.   LOOP  
  16.     j := INSTR (p_str, p_delimiter, i);  
  17.   
  18.     IF j = 0  
  19.     THEN  
  20.         j := len;  
  21.         str := SUBSTR (p_str, i);  
  22.         str_split.EXTEND;  
  23.         str_split (str_split.COUNT) := str;  
  24.   
  25.         IF i >= len  
  26.         THEN  
  27.           EXIT;  
  28.         END IF;  
  29.     ELSE  
  30.         str := SUBSTR (p_str, i, j - i);  
  31.         i := j + len1;  
  32.         str_split.EXTEND;  
  33.         str_split (str_split.COUNT) := str;  
  34.     END IF;  
  35.   END LOOP;  
  36.   
  37.   RETURN str_split;  
  38. END fn_split;  


测试:

 

  1. SQL> select * from table(fn_split('1,2,3,4,5',','));    --第二个单引号中是前面字符串中需要被分隔的字符

    COLUMN_VALUE  

  2. --------------------------------------------------------------------------------  
  3. 1  
  4. 2  
  5. 3  
  6. 4  
  7. 5

    SQL> select * from table(fn_split('1,2,3,4。5','。'));

    COLUMN_VALUE  

  8. --------------------------------------------------------------------------------  
  9. 1,2,3,4  
  10. 5

    SQL>

      


参考:

http://www.itpub.net/thread-1346178-1-1.html

众大牛们已经总结了行列转换的若干方法。今天发现了一种新的方法( ),和大家分享下。
1.SYS.ODCIVARCHAR2LIST:
SELECT COLUMN_VALUE  FROM TABLE(SYS.ODCIVARCHAR2LIST('1','2','3','4','5'));
COLUMN_VALUE
--------------------------------------------------------------------------------
1
2
3
4
5
Oracle 10G 以上版本才支持SYS.ODCIVARCHAR2LIST,其实SYS.ODCIVARCHAR2LIST只不过是一个TYPE,
所以在9I版本中可以通过创建一个TYPE来使用该功能:
CREATE OR REPLACE TYPE MY_ODCIVARCHAR2LIST AS VARRAY(32767) OF VARCHAR2(4000);

SELECT COLUMN_VALUE  FROM TABLE(MY_ODCIVARCHAR2LIST('1','2','3','4','5'));
COLUMN_VALUE
--------------------------------------------------------------------------------
1
2
3
4
5
但是,当'1','2','3','4','5'  作为一个字符串('1,2,3,4,5')就没有办法转换了:
SELECT COLUMN_VALUE  FROM TABLE(MY_ODCIVARCHAR2LIST('1,2,3,4,5'));
COLUMN_VALUE
--------------------------------------------------------------------------------
1,2,3,4,5

总结:(1)Table函数将数组里的内容通过SQL语句查询出来;
      (2)ODCIVARCHAR2LIST 在9I 及以上版本中均可使用。在9I中可通过创建TYPE,10G及以上直接使用SYS.ODCIVARCHAR2LIST;
      (3)ODCIVARCHAR2LIST 适用于字符集,不适用单个字符串,如果是单个字符串,可以通过参考2中(如下)方法实现。

欢迎大家讨论,提出更多更好的方法~~

参考----------------------------------------------------------------
2.其他方法实现列转行(大牛们早已经总结,仅供参考)
(1) 利用CONNECT BY (使用9I,10G,11G)
WITH T AS (SELECT  '1,2,3,4,5' AS STR FROM DUAL)
SELECT  STR1  
FROM ( SELECT  DISTINCT 
                SUBSTR(T.CA,INSTR(T.CA, ',', 1, C.LV) + 1,
                       INSTR(T.CA, ',', 1, C.LV + 1) -(INSTR(T.CA, ',', 1, C.LV) + 1)) AS STR1
       FROM (SELECT ',' || STR || ',' AS CA,LENGTH(STR || ',') -NVL(LENGTH(REPLACE(STR, ',')), 0) AS CNT FROM T) T,
            (SELECT LEVEL LV FROM DUAL CONNECT BY LEVEL <= 9) C
       WHERE C.LV <= T.CNT 
       ORDER BY STR1);
(2).正则表达式(使用10G及以上版本)
WITH TEST AS (SELECT  '1,2,3,4,5' AS STR FROM DUAL)
SELECT DISTINCT REGEXP_SUBSTR(STR, '[^,]+', 1, LEVEL)
FROM TEST
CONNECT BY ROWNUM <= 5;

你可能感兴趣的:(oracle,oracle,行转列)