在PL/SQL中将逗号分隔的字符串转换为数组

Suv*_*kar 37 oracle plsql tokenize

如何将逗号分隔的字符串转换为数组?

我有输入' 1,2,3',我需要将其转换为数组.

小智 47

这是另一个更容易的选择

select to_number(column_value) as IDs from xmltable('1,2,3,4,5');
Run Code Online (Sandbox Code Playgroud)

  • 哇!这对于 PL/SQL 来说读起来非常好:`FOR i IN (SELECT to_number(column_value) as ID FROM xmltable('1,2,3,4,5')) LOOP... END LOOP;` 是最优秀的, 谢谢你! (2认同)

Rob*_*ijk 31

Oracle提供内置函数DBMS_UTILITY.COMMA_TO_TABLE.

不幸的是,这个不适用于数字:

SQL> declare
  2    l_input varchar2(4000) := '1,2,3';
  3    l_count binary_integer;
  4    l_array dbms_utility.lname_array;
  5  begin
  6    dbms_utility.comma_to_table
  7    ( list   => l_input
  8    , tablen => l_count
  9    , tab    => l_array
 10    );
 11    dbms_output.put_line(l_count);
 12    for i in 1 .. l_count
 13    loop
 14      dbms_output.put_line
 15      ( 'Element ' || to_char(i) ||
 16        ' of array contains: ' ||
 17        l_array(i)
 18      );
 19    end loop;
 20  end;
 21  /
declare
*
ERROR at line 1:
ORA-00931: missing identifier
ORA-06512: at "SYS.DBMS_UTILITY", line 132
ORA-06512: at "SYS.DBMS_UTILITY", line 164
ORA-06512: at "SYS.DBMS_UTILITY", line 218
ORA-06512: at line 6
Run Code Online (Sandbox Code Playgroud)

但是通过一个小技巧来为元素加上'x',它可以工作:

SQL> declare
  2    l_input varchar2(4000) := '1,2,3';
  3    l_count binary_integer;
  4    l_array dbms_utility.lname_array;
  5  begin
  6    dbms_utility.comma_to_table
  7    ( list   => regexp_replace(l_input,'(^|,)','\1x')
  8    , tablen => l_count
  9    , tab    => l_array
 10    );
 11    dbms_output.put_line(l_count);
 12    for i in 1 .. l_count
 13    loop
 14      dbms_output.put_line
 15      ( 'Element ' || to_char(i) ||
 16        ' of array contains: ' ||
 17        substr(l_array(i),2)
 18      );
 19    end loop;
 20  end;
 21  /
3
Element 1 of array contains: 1
Element 2 of array contains: 2
Element 3 of array contains: 3

PL/SQL procedure successfully completed.
Run Code Online (Sandbox Code Playgroud)

问候,Rob.

  • 如果要拆分的字符串包含空格,则不起作用 (2认同)
  • 来自:[将分隔列表转换为集合(反之亦然)](http://www.oratechinfo.co.uk/delimited_lists_to_collections.html)_`COMMA_TO_TABLE`(反向`TABLE_TO_COMMA`)不是为此目的编写的! _ ...它们主要是由Oracle内部复制编写的,并且解析IDENTIFIERS而不是字符串,因此必须是有效的Oracle对象名. (2认同)

Ray*_*eng 12

我们永远不会用不同的方式来做同样的事情,对吧?我最近发现这非常方便:

DECLARE
   BAR   VARCHAR2 (200) := '1,2,3';
BEGIN
   FOR FOO IN (    SELECT REGEXP_SUBSTR (BAR,
                                         '[^,]+',
                                         1,
                                         LEVEL)
                             TXT
                     FROM DUAL
               CONNECT BY REGEXP_SUBSTR (BAR,
                                         '[^,]+',
                                         1,
                                         LEVEL)
                             IS NOT NULL)
   LOOP
      DBMS_OUTPUT.PUT_LINE (FOO.TXT);
   END LOOP;
END;
Run Code Online (Sandbox Code Playgroud)

输出:

1
2
3
Run Code Online (Sandbox Code Playgroud)


Mal*_*ous 9

我知道Stack Overflow对粘贴URL没有任何解释感到皱眉,但这个特定页面有一些非常好的选择:

http://www.oratechinfo.co.uk/delimited_lists_to_collections.html

我特别喜欢这个,它将分隔列表转换为临时表,您可以对以下内容运行查询:

/* Create the output TYPE, here using a VARCHAR2(100) nested table type */

SQL> CREATE TYPE test_type AS TABLE OF VARCHAR2(100);
  2  /

Type created.

/* Now, create the function.*/

SQL> CREATE OR REPLACE FUNCTION f_convert(p_list IN VARCHAR2)
  2    RETURN test_type
  3  AS
  4    l_string       VARCHAR2(32767) := p_list || ',';
  5    l_comma_index  PLS_INTEGER;
  6    l_index        PLS_INTEGER := 1;
  7    l_tab          test_type := test_type();
  8  BEGIN
  9    LOOP
 10      l_comma_index := INSTR(l_string, ',', l_index);
 11      EXIT WHEN l_comma_index = 0;
 12      l_tab.EXTEND;
 13      l_tab(l_tab.COUNT) := SUBSTR(l_string, l_index, l_comma_index - l_index);
 14      l_index := l_comma_index + 1;
 15    END LOOP;
 16    RETURN l_tab;
 17  END f_convert;
 18  /

Function created.
Run Code Online (Sandbox Code Playgroud)
/* Prove it works */

SQL> SELECT * FROM TABLE(f_convert('AAA,BBB,CCC,D'));

COLUMN_VALUE
--------------------------------------------------------------------------------
AAA
BBB
CCC
D

4 rows selected.
Run Code Online (Sandbox Code Playgroud)