=====Oracle PL/SQL Tokenizer - Strings zerlegen ===== **Aufgabe:** Ein Liste soll wieder in einzelne Werte zerlegt werden Um solch einen String zu erzeugen => siehe auch [[prog:sql_liste_erstellen|Ein Listen von Werten in SQL erstellen]] ---- ====APEX_UTIL.STRING_TO_TABLE==== Alternativ in Apex die Methode: DECLARE v_selected APEX_APPLICATION_GLOBAL.VC_ARR2; BEGIN -- -- Convert the colon separated string of values into -- a PL/SQL array v_selected := APEX_UTIL.STRING_TO_TABLE(:P100_PRODUCTLIST); -- -- Loop over array to insert department numbers and sysdate -- FOR i IN 1..v_selected.count LOOP dbms_output.put_line(v_selected(i)); END LOOP; END; ---- ==== in PL/SQL eine Liste wieder zerlegen mit DBMS_UTILITY ==== Mit Hilfe von **dbms_utility.comma_to_table** lässt sich eine Liste in ein Array transformieren. Beispiel: declare v_values DBMS_UTILITY.lname_array; v_tabLength BINARY_INTEGER; -- not working v_list varchar2(255):=replace('0100:26941:0:0',':',','); -- working -- v_list varchar2(255):=replace('a:b:c:d',':',','); BEGIN dbms_output.put_line(v_list); DBMS_UTILITY.COMMA_TO_TABLE( list => v_list , tablen => v_tabLength , tab => v_values ); if v_tabLength=4 then dbms_output.put_line('INST_KEY :='|| v_values(1)); dbms_output.put_line('KONTONUMMER :='|| v_values(2)); dbms_output.put_line('KONTO_SUBNUMMER :='|| v_values(3)); dbms_output.put_line('LIMITSEQUENZ :='|| v_values(4)); else raise_application_error( -20020, 'Konto Key has not enough values ::' || v_list); end if; END; siehe auch: http://docs.oracle.com/cd/E11882_01/timesten.112/e21645/d_util.htm#i1002468 == BUG - Falls String nur aus Zahlen wie "1,2,3,5" besteht == In meiner 12c Umgebung erhalten ich allerdings den folgenden Fehler wenn der String aus Zahlen besteht: ERROR at line 1: ORA-20001: comma-separated list invalid near # ORA-06512: at "SYS.DBMS_UTILITY", line 236 ORA-06512: at "SYS.DBMS_UTILITY", line 272 ORA-06512: at line 16 Daher meine eigene Routine erstellt, da mir gerade die Apex Methode nicht mehr einfällt ... ---- ==== PL/SQL Routine zum Zerlegen eines Strings ==== Seperator kann eine beliebige Zeichenkette sein. create or replace PACKAGE GPI_APEX_UTILS AS -- ===================== type splitResultTab IS TABLE OF VARCHAR2(2000) INDEX BY BINARY_INTEGER; -- ===================== -- split a string -- ===================== function splitString( p_string varchar2 , p_seperator varchar2) return splitResultTab; -- ===================== -- test the function --- ===================== procedure testsplitString( p_string varchar2 , p_seperator varchar2); END GPI_APEX_UTILS; / create or replace PACKAGE body GPI_APEX_UTILS -- ===================== -- split a string -- ===================== function splitString ( p_string varchar2 , p_seperator varchar2) return splitResultTab is v_returnTab splitResultTab; v_token_count pls_integer; v_tocken varchar2(2000); v_string varchar2(32000); v_pos1 pls_integer; v_sep_length pls_integer; begin -- get the count of the tocken (count sperator + one ) v_token_count:= REGEXP_COUNT(p_string,p_seperator)+1; v_sep_length:=length(p_seperator); if v_token_count=1 then raise_application_error( -20020, ' seperator Char not exist in string to split - p_seperator:=' || p_seperator ); end if; -- add at the end on seperator sign as end signal for the loop! v_string:=p_string||p_seperator; -- loop of the result string -- in each round cut off the tocken at the begin of the string for i in 1 .. v_token_count loop -- find the first delimiter in the string v_pos1 :=instr(v_string,p_seperator); -- get the tocken v_tocken:=substr(v_string,1,v_pos1-1); v_returnTab(i):=v_tocken; -- cut the read tocken from the string v_string:=substr(v_string,v_pos1+v_sep_length,length(v_string)); end loop; return v_returnTab; end splitString; -- ===================== -- test the function --- ===================== procedure testsplitString( p_string varchar2 , p_seperator varchar2) is v_resTab splitResultTab; begin v_resTab:=splitString(p_string=> p_string, p_seperator => p_seperator); FOR i IN v_resTab.FIRST .. v_resTab.LAST LOOP -- ausgeben IF v_resTab.EXISTS(i) THEN DBMS_OUTPUT.put_line('element #' || i || ' = ' || v_resTab(i)); END IF; END LOOP; end; END GPI_APEX_UTILS; Testen: sqlplus gpi/gpi exec GPI_APEX_UTILS.testsplitString('0100::26941::0::0','::') element #1 = 0100 element #2 = 26941 element #3 = 0 element #4 = 0 ---- ==== RegEx Lösungen ==== * http://stackoverflow.com/questions/31654411/split-string-by-space-and-character-as-delimiter-in-oracle-with-regexp-substr * https://blogs.oracle.com/aramamoo/entry/how_to_split_comma_separated_string_and_pass_to_in_clause_of_select_statement ---- ==== Quellen ==== Mehr => [[prog:plsql_code_pices|PL/SQL - Code Beispiele]]