web-dev-qa-db-fra.com

Comment analyser une chaîne délimitée par des virgules en PL/SQL?

J'ai une chaîne délimitée par des virgules dans un script PL/SQL (par exemple, data: = 'a, b, c, d, e'), que je dois analyser dans le script.

Je voudrais parcourir la chaîne et traiter chaque élément. Comme une boucle "foreach".

Est-ce possible en PL/SQL? Est-ce que quelqu'un peut m'indiquer du code?

15
TERACytE

Si vous utilisez Oracle 10G ou 11G, vous devriez avoir une fonction Apex intégrée apex_util.string_to_table:

SQL> declare
  2    v_array apex_application_global.vc_arr2;
  3    v_string varchar2(2000);
  4  begin
  5  
  6    -- Convert delimited string to array
  7    v_array := apex_util.string_to_table('alpha,beta,gamma,delta', ',');
  8    for i in 1..v_array.count
  9    loop
 10      dbms_output.put_line(v_array(i));
 11    end loop;
 12  
 13    -- Convert array to delimited string
 14    v_string := apex_util.table_to_string(v_array,'|');
 15    dbms_output.put_line(v_string);
 16  end;
 17  /
alpha
beta
gamma
delta
alpha|beta|gamma|delta

PL/SQL procedure successfully completed.
14
Tony Andrews

Oracle 11g:

SELECT   num_value
  FROM   (    SELECT   TRIM (REGEXP_SUBSTR (num_csv,
                                            '[^,]+',
                                            1,
                                            LEVEL))
                          num_value
                FROM   (    SELECT   '1,2,3,4,5,6,7,8,9,10' num_csv FROM DUAL)
          CONNECT BY   LEVEL <= regexp_count (num_csv, ',', 1) + 1)
 WHERE   num_value IS NOT NULL
4
Julfcar Ali

Voici brièvement un exemple simple:

declare
  string_to_parse varchar2(2000) := 'abc,def,ghi,klmno,pqrst';
  l_count number;
  l_value   varchar2(2000);
begin
  string_to_parse := string_to_parse||',';
  l_count := length(string_to_parse) - length(replace(string_to_parse,',',''));
  -- In Oracle 11g use regexp_count to determine l_count
  for i in 1 .. l_count loop 
    select regexp_substr(string_to_parse,'[^,]+',1,i)
    into l_value
    from dual;
    dbms_output.put_line(l_value);
  end loop;
end;
2
java.nazif

Une simple instruction SQL tokenizer fonctionnant pour Oracle 10g et 11g pourrait être écrite comme suit:

WITH string AS (
      SELECT pv_string value 
        FROM dual)
SELECT DISTINCT upper(trim(regexp_substr (value, '[^' || pv_separator || ']+', 1, ROWNUM))) value,
       level
  FROM string
CONNECT BY LEVEL <= LENGTH(regexp_replace (value, '[^' || pv_separator || ']+')) + 1
  ORDER BY level;

Où vous pouvez remplacer pv_string par la chaîne à analyser (par exemple, 'a, b, c, d, e') et pv_separator par la chaîne de séparation (par exemple, ',').

0
Guillaume