Convert comma separated string to array in PL/SQL

前端 未结 14 2174
没有蜡笔的小新
没有蜡笔的小新 2020-11-27 03:19

How do I convert a comma separated string to a array?

I have the input \'1,2,3\' , and I need to convert it into an array.

相关标签:
14条回答
  • 2020-11-27 03:49

    Simple Code

        create or replace function get_token(text_is varchar2, token_in number, delim_is varchar2 := ';') return varchar2 is
           text_ls varchar2(2000);
           spos_ln number;
           epos    _ln number;
        begin
           text_ls := delim_is || text_is || rpad(delim_is, token_in, delim_is);
           spos_ln := instr(text_ls, delim_is, 1, token_in);
           epos_ln := instr(text_ls, delim_is, 1, token_in+1);
           return substr(text_ls, spos_ln+1, epos_ln-spos_ln-1);
        end get_token;
    
    0 讨论(0)
  • 2020-11-27 03:52

    here is another easier option

    select to_number(column_value) as IDs from xmltable('1,2,3,4,5');
    
    0 讨论(0)
  • 2020-11-27 03:55

    I know Stack Overflow frowns on pasting URLs without explanations, but this particular page has a few really good options:

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

    I particularly like this one, which converts the delimited list into a temporary table you can run queries against:

    /* 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.
    

    /* Prove it works */
    
    SQL> SELECT * FROM TABLE(f_convert('AAA,BBB,CCC,D'));
    
    COLUMN_VALUE
    --------------------------------------------------------------------------------
    AAA
    BBB
    CCC
    D
    
    4 rows selected.
    
    0 讨论(0)
  • 2020-11-27 03:55

    I was looking for a similar solution where I had multi-byte characters (hyphen, whitespace, underscore) in comma separated lists. So dbms_utility.comma_to_table didn't work for me.

    declare
      curr_val varchar2 (255 byte);
      input_str varchar2 (255 byte);
      remaining_str varchar2 (255 byte);
    begin
      remaining_str := input_str || ',dummy';  -- this value won't output
      while (regexp_like (remaining_str, '.+,.+'))
      loop
        curr_val := substr (remaining_str, 1, instr (remaining_str, ',') - 1);
        remaining_str = substr (remaining_str, instr (remaining_str, ',') + 1);
        dbms_output.put_line (curr_val);
      end loop;
    end;
    

    This is not an expert answer so I hope someone would improve this answer.

    0 讨论(0)
  • 2020-11-27 03:56

    Using a pipelined table function:

    SQL> CREATE OR REPLACE TYPE test_type
      2  AS
      3    TABLE OF VARCHAR2(100)
      4  /
    
    Type created.
    
    SQL> CREATE OR REPLACE FUNCTION comma_to_table(
      2      p_list IN VARCHAR2)
      3    RETURN test_type PIPELINED
      4  AS
      5    l_string LONG := p_list || ',';
      6    l_comma_index PLS_INTEGER;
      7    l_index PLS_INTEGER := 1;
      8  BEGIN
      9    LOOP
     10      l_comma_index := INSTR(l_string, ',', l_index);
     11      EXIT
     12    WHEN l_comma_index = 0;
     13      PIPE ROW ( TRIM(SUBSTR(l_string, l_index, l_comma_index - l_index)));
     14      l_index := l_comma_index                                + 1;
     15    END LOOP;
     16  RETURN;
     17  END comma_to_table;
     18  /
    
    Function created.
    

    Let's see the output:

    SQL> SELECT *
      2  FROM TABLE(comma_to_table('12 3,456,,,,,abc,def'))
      3  /
    
    COLUMN_VALUE
    ------------------------------------------------------------------------------
    12 3
    456
    
    
    
    
    abc
    def
    
    8 rows selected.
    
    SQL>
    
    0 讨论(0)
  • 2020-11-27 03:59

    A quick search on my BBDD took me to a function called split:

    create or replace function split
    ( 
    p_list varchar2, 
    p_del varchar2 := ','
    ) 
    return split_tbl pipelined
    is 
    l_idx pls_integer; 
    l_list varchar2(32767) := p_list;AA 
    l_value varchar2(32767);
    begin 
    loop 
    l_idx := instr(l_list,p_del); 
    if l_idx > 0 then 
    pipe row(substr(l_list,1,l_idx-1)); 
    l_list := substr(l_list,l_idx+length(p_del));
    else 
    pipe row(l_list); 
    exit; 
    end if; 
    end loop; 
    return;
    end split;
    

    I don't know if it'll be of use, but we found it here...

    0 讨论(0)
提交回复
热议问题