| Funktionen erzeugen |
|
|
| Donnerstag, 16. Oktober 2008 um 17:36 | ||||
|
Wir wollen in dieser Lektion den Unterschied zwischen einer Funktion und Prozedur ausarbeiten. Wir werden eine Funktion erzeugen, die es erlaubt, Mitarbeiterdatensätze zu verändern. Diese dürfen aber nur während der Geschäftszeiten verändert werden, denn wir wollen nicht, dass die Reinigungskräfte des Nachts ihre Gehälter erhöhen. Grundsätzlich kann eine Funktion all das tun, was eine Prozedur auch kann, z.B. andere Funktionen oder Prozeduren aufrufen. Zusätzlich kann und muß eine Funktion auch einen Wert als Ergebnis zurückliefern. Wieder erzeugen wir erst einmal den “Rahmen” unserer Funktion: create or replace function plsql19 return boolean is Beachten Sie die return boolean Klausel. Die Funktion liefert einen boolschen Wert, also entweder Wahr oder Falsch zurück, abhängig davon, ob die Veränderung des Datensatzes erfolgreich war. Nun erzeugen wir Funktionalität: create or replace function plsql19 Die Funktion kennt zwei Eingabe-Argumente, über die gesteuert wird, welcher Mitarbeiter welches neue Gehalt erhält. Wegen der verankerten Deklaration der Datentypen ist Voraussetzung, dass eine Tabelle employees mit den referenzierten Spalten tatsächlich existiert. Wenn wir die Funktion über DESCRIBE betrachten, erhalten wir FUNCTION plsql19 RETURNS BOOLEAN Hier sehen wir also, welche Eingabe-Argumente zulässig sind und welcher Datentyp zurückgeliefert wird. Hier ist die Struktur der EMPLOYEES-Tabelle SQL>desc employees Und hier der Inhalt SQL>select * from employees; Jetzt testen wir die Funktion: Um eine Funktion zu testen, können wir nicht einfach ihren Namen in SQL*Plus eintippen, da sie ja einen Wert zurückliefert und wir einen “Container” brauchen, der den zurückgelieferten Wert aufnimmt. Wir müssen also die Funktion aus PL/SQL heraus aufrufen. Hier ist unser anonymer Block, um die Funktion zu testen: begin Denken Sie daran, dass SERVEROUTPUT ON gesetzt sein muß, damit Sie ein Ergebnis sehen. Wenn Sie so sind wie ich und abends arbeiten, sehen Sie Try again tomorrow morning. Sollten Sie Ihren Source-Code nicht gespeichert haben, gibt es ja noch das Data Dictionary, in dem unsere Funktion im Source-Code vorliegt. SQL> select text from all_source where name = 'PLSQL19' order by line; Um die Funktion zu verändern, folgen Sie den Schritten
Voila, die Funktion ist verändert! Funktionen in SQL-AnweisungenDas beste ist, dass Funktionen auch in SQL-Anweisungen genutzt werden können. Wir können uns also eine Funktion brutto vorstellen, die auf einen übergeben Nettowert die Mehrwertsteuer addiert. create or replace function brutto (nettowert IN number) return number is Solche Funktionen können sowohl in einem SELECT wie auch in jeder anderen DML Anweisung genutzt werden, also z.B. SQL>select artikel_netto, brutto(artikel_netto) from artikel; oder in SQL>update rechnung set brutto_position = brutto(netto_pos); Ein Kenner der Materie würde an dieser Stelle auch auf das Pragma AUTONOMOUS_TRANSACTION hinweisen, mit dem einige Einschränkungen der Verwendung von Funktionen innerhalb SQL aufgehoben werden.
|
||||
| Aktualisiert ( Donnerstag, 30. September 2010 um 09:02 ) | ||||


Kommentare
Generell finde ich es geschickter, Vergleiche immer in dem Datentyp zu machen, in dem die Daten vorliegen. Im Falle der Uhrzeit ist das aber kein Problem, weil der Stringvergleich der Uhrzeit immer korrekt gemacht wird. Anders wäre es bei dd.mm.
Dann ist der 03.05. plötzlich kleiner als der 07.02.
Beim Ausprobieren ist mir aber was ganz anderes aufgefallen: Zwar wird mit meinen to_date Funktionen die Richtige Uhrzeit ans Datum drangehängt. Aber ORACLE scheint das Datum auf den Beginn des Monats zu runden. Also: to_date('09:00','hh24:mi') ergibt (heute ist der 30.09.2010): '01.09.2010 09:00'.
Meine Funktion ist also fehlerhaft.
Und das Subselect mit der EXIST-Klausel kann man sich natürlich auch sparen.
Ich passe die Funktion entspr. Deiner Vorschläge an.
LG
Martin Zitieren
Wäre "to_char(sysdate , 'hh24:mi') between '09:00' and '17:30'" nicht besser als
"sysdate between to_date('09:00', 'hh24:mi') and to_date('17:30', 'hh24:mi')"?
Tschüß,
Piet Zitieren
Alle Kommentare dieses Beitrages als RSS-Feed.