Die Elemente, die aus der Zerlegung hervorgehen, werden in einer Nested Table gespeichert:
create or replace type string_nt as table of varchar2(100); /Natürlich kann die Aufgabe auch mit PL/SQL gelöst werden, jedoch enthält Java bereits eine Methode zur Lösung des Problems; die Methode
split
der Klasse String
.create or replace and compile java source named string_utilities as import java.sql.Connection; import java.sql.DriverManager; import oracle.sql.ARRAY; import oracle.sql.ArrayDescriptor; public class StringUtilities { public static ARRAY split(String input, String delimiter) throws Exception { Connection connection = DriverManager.getConnection("jdbc:default:connection:"); ArrayDescriptor aDesc = ArrayDescriptor.createDescriptor("STRING_NT", connection); String[] elements = input.split(delimiter); return new ARRAY(aDesc, connection, elements); } } /Der Java-Code ruft die Methode
split
auf, um das erste Argument in seine Bestandteile zu zerlegen. Das zweite Argument beschreibt das Trennzeichen als regulären Ausdruck.Nun fehlt nur noch die Funktion in PL/SQL, um die Methode verwenden zu können.
create or replace function split_string ( p_string_in in varchar2, p_delimiter_in in varchar2 ) return string_nt is language java name 'StringUtilities.split(java.lang.String, java.lang.String) return oracle.sql.ARRAY'; /Da der Rückgabetyp der Funktion eine Collection (Nested Table) ist, erfolgt der Aufruf im FROM-Teil des Select-Statements mit dem Table-Keyword.
select column_value from table(split_string('a,b,c,d', ','));
COLUMN_VALUE ------------- a b c dWie bereits angedeutet, wird das Trennzeichen als regulärer Ausdruck interpretiert. Das folgende Beispiel trennt die Elemente bei einem '#' oder einem '/'.
select column_value from table(split_string('a#b/c#d', '(#|/)'));
COLUMN_VALUE ------------- a b c dDurch die Beschreibung als regulärer Ausdruck können auch sehr komplexe Trennzeichen beschrieben werden.
Abschließend sei noch erwähnt, dass die Funktion natürlich auch in PL/SQL verwendet werden kann, wie das folgende Beispiel zeigt:
declare v_columns string_nt := split_string('empno;ename;job;sal', ';'); begin for i in v_columns.first .. v_columns.last loop dbms_output.put_line(i || ': ' || v_columns(i)); end loop; end; /
1: empno 2: ename 3: job 4: sal