martinbulinski.de

Wie funktioniert eine pipelined function Drucken E-Mail
  
Donnerstag, 13. November 2008 um 15:52

Nicht immer müssen Tabellenzeilen aus einer Datenbanktabelle stammen. Es gibt Situationen, in denen Tabellendaten dynamisch ermittelt werden sollen. Bspw. bittet mich ein PHP-Entwickler, ihm eine Tabelle mit Wochentagen bereitzustellen, damit er einen Terminkalender erzeugen kann. Wer deswegen eine Tabelle Kalendertag erzeugt und darin alle Wochentage des laufenden und womöglich der folgenden Jahre speichert, macht sich unnötig Arbeit. Pipelined functions sind Deine Freunde!

 

Pipelined Functions sind PL/SQL-Objekte, die nicht skalare Werte liefern, sondern mehrere Werte in Tabellenform liefern. Diese Tabellenform ist Voraussetzung, damit eine Nutzung mit SQL-Mitteln überhaupt möglich ist.

Beim Anlegen der Funktion muss der Rückgabetyp der Funktion auf Datenbankseite bereits angelegt sein. Das könnte zum Beispiel so aussehen:

create type datumsliste is table of date;
/

Dieser Datentyp kann jetzt von Funktionen genutzt werden.

Beim Anlegen der Funktion richten wir uns nach der Syntax, die auch für normale Funktionen gilt. Der einzige Unterschied ist das Schlüsselwort PIPELINED, das hinter dem Rückgabetyp der Funktion steht.

Im ausführbaren Teil der Funktion können wir nun Zeile für Zeile liefern mit der Anweisung PIPE ROW, gefolgt vom Datenwert. Dieser muß natürlich typkompatibel zum Typ sein, den wir beim Erzeugen des Tabellentypen genutzt haben.
Jede PL/SQL-Funktion verlangt die Existenz einer RETURN-Anweisung (das wird beim Anlegen geprüft, ob diese Anweisung bei der Programmausführung tatsächlich angesprungen wird, ist dabei unerheblich). Weil hier die Ergebnisse nicht erst mit RETURN, sondern bereits zuvor zeilenweise mit der PIPE ROW Anweisung geliefert wurden, darf das RETURN keinen Wert zurückliefern.

Meine Funktion liefert alle Tage des Monats des Datums, das beim Aufruf übergeben wurde.

create or replace function tage_des_monats (datum date) return datumsliste
pipelined is
	erster_tag date;
begin
	erster_tag := trunc(datum,'MONTH');
	for i in 0 .. 30 loop
                    exit when (erster_Tag+i) > last_day(datum);
  	    pipe row (erster_Tag+i);
	end loop;
	return;
end;
/

Die Variable erster_tag enthält den ersten Tag des Monats des übergebenen Datums, in der Schleife mache ich 31 Durchläufe, wobei ich die Schleife bereits vorher verlasse, wenn der Monat weniger Tage hat.
Bei jedem Schleifendurchlauf liefert die Funktion einen Datensatz zurück.

Ein Aufruf dieser Funktion in SQL kann dann erfolgen mit

select * from table(tage_des_monats(sysdate));

um alle Tage des laufenden Monats zu erhalten.

Nun wäre noch zu prüfen, ob die pipelined function performanter ist als ein entsprechendes SQL-Statement. Das SQL-Pendant finden Sie unter: alle Tage des laufenden Monats ermitteln

 
Benutzerbewertung: / 1
SchwachPerfekt 

Kommentar schreiben


Sicherheitscode
Aktualisieren

Anmeldung



Wer ist online

Wir haben 8 Gäste online