在oracle中拆分函数以逗号分隔值和自动序列

AKB*_*ALI 25 oracle plsql split function delimiter

需要拆分功能,它将采用两个参数,字符串拆分和分隔符来拆分字符串并返回一个包含列Id和Data的表.如何调用Split函数,它将返回一个包含列Id和Data的表.Id列将包含序列,数据列将包含该字符串的数据.例如.

SELECT*FROM Split('A,B,C,D',',')
Run Code Online (Sandbox Code Playgroud)

结果应采用以下格式:

|Id | Data
 --   ----
|1  | A  |
|2  | B  |
|3  | C  |
|4  | D  |
Run Code Online (Sandbox Code Playgroud)

Dav*_*ber 21

以下是如何创建这样的表:

 SELECT LEVEL AS id, REGEXP_SUBSTR('A,B,C,D', '[^,]+', 1, LEVEL) AS data
   FROM dual
CONNECT BY REGEXP_SUBSTR('A,B,C,D', '[^,]+', 1, LEVEL) IS NOT NULL;
Run Code Online (Sandbox Code Playgroud)

通过一些调整(即,用变量替换,in [^,]),您可以编写这样的函数来返回表.


Lal*_*r B 18

有多种选择.请参阅在Oracle中将单个逗号分隔的字符串拆分为行

您只需要在选择列表中添加LEVEL作为列,以获取返回的每行的序列号.或者,ROWNUM也足够了.

使用以下任何SQL,您可以将它们包含在FUNCTION中.

INSTRCONNECT BY子句中:

SQL> WITH DATA AS
  2    ( SELECT 'word1, word2, word3, word4, word5, word6' str FROM dual
  3    )
  4  SELECT trim(regexp_substr(str, '[^,]+', 1, LEVEL)) str
  5  FROM DATA
  6  CONNECT BY instr(str, ',', 1, LEVEL - 1) > 0
  7  /

STR
----------------------------------------
word1
word2
word3
word4
word5
word6

6 rows selected.

SQL>

REGEXP_SUBSTRCONNECT BY子句:

SQL> WITH DATA AS
  2    ( SELECT 'word1, word2, word3, word4, word5, word6' str FROM dual
  3    )
  4  SELECT trim(regexp_substr(str, '[^,]+', 1, LEVEL)) str
  5  FROM DATA
  6  CONNECT BY regexp_substr(str , '[^,]+', 1, LEVEL) IS NOT NULL
  7  /

STR
----------------------------------------
word1
word2
word3
word4
word5
word6

6 rows selected.

SQL>

REGEXP_COUNTCONNECT BY子句:

SQL> WITH DATA AS
  2        ( SELECT 'word1, word2, word3, word4, word5, word6' str FROM dual
  3        )
  4      SELECT trim(regexp_substr(str, '[^,]+', 1, LEVEL)) str
  5      FROM DATA
  6      CONNECT BY LEVEL 

使用XMLTABLE

SQL> WITH DATA AS
  2    ( SELECT 'word1, word2, word3, word4, word5, word6' str FROM dual
  3    )
  4  SELECT trim(COLUMN_VALUE) str
  5    FROM DATA, xmltable(('"' || REPLACE(str, ',', '","') || '"'))
  6  /
STR
------------------------------------------------------------------------
word1
word2
word3
word4
word5
word6

6 rows selected.

SQL>

使用MODEL子句:

SQL> WITH t AS
  2  (
  3         SELECT 'word1, word2, word3, word4, word5, word6' str
  4         FROM   dual ) ,
  5  model_param AS
  6  (
  7         SELECT str AS orig_str ,
  8                ','
  9                       || str
 10                       || ','                                 AS mod_str ,
 11                1                                             AS start_pos ,
 12                Length(str)                                   AS end_pos ,
 13                (Length(str) - Length(Replace(str, ','))) + 1 AS element_count ,
 14                0                                             AS element_no ,
 15                ROWNUM                                        AS rn
 16         FROM   t )
 17  SELECT   trim(Substr(mod_str, start_pos, end_pos-start_pos)) str
 18  FROM     (
 19                  SELECT *
 20                  FROM   model_param MODEL PARTITION BY (rn, orig_str, mod_str)
 21                  DIMENSION BY (element_no)
 22                  MEASURES (start_pos, end_pos, element_count)
 23                  RULES ITERATE (2000)
 24                  UNTIL (ITERATION_NUMBER+1 = element_count[0])
 25                  ( start_pos[ITERATION_NUMBER+1] = instr(cv(mod_str), ',', 1, cv(element_no)) + 1,
 26                  end_pos[iteration_number+1] = instr(cv(mod_str), ',', 1, cv(element_no) + 1) ) )
 27  WHERE    element_no != 0
 28  ORDER BY mod_str ,
 29           element_no
 30  /

STR
------------------------------------------
word1
word2
word3
word4
word5
word6

6 rows selected.

SQL>

您还可以使用Oracle提供的DBMS_UTILITY包.它提供各种实用程序子程序.一个这样有用的实用程序是COMMA_TO_TABLE过程,它将逗号分隔的名称列表转换为名称的PL/SQL表.

阅读DBMS_UTILITY.COMMA_TO_TABLE


MT0*_*MT0 6

Oracle安装程序:

CREATE OR REPLACE FUNCTION split_String(
  i_str    IN  VARCHAR2,
  i_delim  IN  VARCHAR2 DEFAULT ','
) RETURN SYS.ODCIVARCHAR2LIST DETERMINISTIC
AS
  p_result       SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST();
  p_start        NUMBER(5) := 1;
  p_end          NUMBER(5);
  c_len CONSTANT NUMBER(5) := LENGTH( i_str );
  c_ld  CONSTANT NUMBER(5) := LENGTH( i_delim );
BEGIN
  IF c_len > 0 THEN
    p_end := INSTR( i_str, i_delim, p_start );
    WHILE p_end > 0 LOOP
      p_result.EXTEND;
      p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, p_end - p_start );
      p_start := p_end + c_ld;
      p_end := INSTR( i_str, i_delim, p_start );
    END LOOP;
    IF p_start <= c_len + 1 THEN
      p_result.EXTEND;
      p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, c_len - p_start + 1 );
    END IF;
  END IF;
  RETURN p_result;
END;
/
Run Code Online (Sandbox Code Playgroud)

询问

SELECT ROWNUM AS ID,
       COLUMN_VALUE AS Data
FROM   TABLE( split_String( 'A,B,C,D' ) );
Run Code Online (Sandbox Code Playgroud)

输出:

ID DATA
-- ----
 1 A
 2 B
 3 C
 4 D
Run Code Online (Sandbox Code Playgroud)