Posts mit dem Label Type werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Type werden angezeigt. Alle Posts anzeigen

Donnerstag, 6. Oktober 2011

Zeichenketten zerlegen mithilfe von Java in der Datenbank

Heute geht's um die Zerlegung von Zeichenketten. Dabei soll die Trennung durch ein Trennzeichen vorgenommen werden, welches auch als regulärer Ausdruck angegeben werden kann. Die Zeichenkette 'a,b,c' enthält drei, durch Kommata getrennte, Elemente. Eine Zerlegung, mit dem Komma als Trennzeichen, soll dann die Elemente 'a', 'b' und 'c' enthalten.

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
d       
Wie 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
d     
Durch 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