Benutzer-Werkzeuge

Webseiten-Werkzeuge


prog:plsql_string_tokenizer

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
prog:plsql_string_tokenizer [2016/11/08 09:24]
gpipperr [APEX_UTIL.STRING_TO_TABLE]
prog:plsql_string_tokenizer [2016/11/08 09:24] (aktuell)
gpipperr [APEX_UTIL.STRING_TO_TABLE]
Zeile 1: Zeile 1:
 +=====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:
 +
 +<code plsql> 
 +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;
 +</code>
 +----
 +
 +==== 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:
 +<code SQL>
 +
 +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;
 +</code>
 +
 +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:
 +
 +<code>
 +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
 +</code>
 +
 +
 +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.
 +
 +
 +<code plsql>
 +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;
 +
 +</code>
 +
 +
 +Testen:
 +
 +<code sql>
 +
 +sqlplus gpi/gpi
 +
 +exec GPI_APEX_UTILS.testsplitString('0100::26941::0::0','::')
 +
 +element #1 = 0100
 +element #2 = 26941
 +element #3 = 0
 +element #4 = 0
 +
 +</code>
 +
 +----
 +
 +==== 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]]
"Autor: Gunther Pipperr"
prog/plsql_string_tokenizer.txt · Zuletzt geändert: 2016/11/08 09:24 von gpipperr