[ORACLE] Funktion ... Syntax?

J-C

Mitglied
Hallo... komme bei der Funktion nicht weiter, er meckert immer und sagt:

ERROR at line 25: PLS-00103: Encountered the symbol "THEN" when expecting one of the following: := . ( % ; 1. CREATE OR REPLACE FUNCTION monatspreis (
2. vertragsbeginn in date,

3. vertragsende in date,
4. monat in number,
hier die Funktion.... könnt ihr mir sagen wo der Fehler liegt... hab jetzt schon 2 Stunden probiert... sollte eigentlich vom syntax her richtig sein!

Code:
CREATE OR REPLACE FUNCTION monatspreis (
   vertragsbeginn in date,
   vertragsende in date,
   monat in number,
   jahr in number,
   listenpreis in number,
   rabatt in number,
   anzahl in number 
 ) RETURN number IS
 
 ergebnis number;
 
BEGIN
    IF 
      ((to_char(vertragsbeginn,'dd') = 1 
      AND to_char(vertragsbeginn,'mm') = monat 
      AND to_char(vertragsbeginn,'yy') = jahr)
     OR (to_char(vertragsbeginn,'yy') < jahr
      AND to_char(vertragsende,'yy') = jahr
      AND to_char(vertragsende,'mm') >= monat))
    THEN ergebnis := ((listenpreis -(listenpreis*(rabatt/100)))*anzahl);
    ELSEIF (to_char(vertragsbeginn,'dd') > 1 
      AND to_char(vertragsbeginn,'mm') = monat 
      AND to_char(vertragsbeginn,'yy') = jahr)
    THEN ergebnis := ((((listenpreis-(listenpreis*rabatt/100))/30)* (31 -(to_char(vertragsbeginn,'dd')))* Anzahl));
    ELSEIF ((to_char(vertragsbeginn,'mm') = monat 
      AND to_char(vertragsende,'mm') >= monat 
      AND to_char(vertragsbeginn,'yy') = jahr)
     OR (to_char(vertragsende,'yy') > jahr
      AND to_char(vertragsbeginn,'yy') = jahr
      AND to_char(vertragsbeginn,'mm') <= monat))
    THEN ergebnis := ((listenpreis -(listenpreis*(rabatt/100)))*anzahl);
    ELSE ergebnis := (listenpreis - listenpreis);
    END IF
    return ergebnis;
END
 
Hi,

Nein, die Syntax ist nicht korrekt, sonst würde der Interpreter ja nicht meckern ;)

Wie es scheint ist nach der Bedingung des letzten IFs eine Klammer zu viel
 
Nee... an den Klammern liegt es nicht.... komisch.. hab jetzt einfach davor CASE geschrieben und alle IF/ELSEIF durch WHEN ersetzt... voila... es geht
 
Nun, ohne deine Funktion zu testen würde ich sagen, dass ein ";" hinter dem END IF fehlt.
Ich hätte aber noch eine kleine Anmerkung zu der Funktion. Leider zwingst du Oracle zu extrem vielen Typkonvertierungen.
Das kostet Zeit und Performance! Als Beispiel: Deine Eingangsvariable Monat ist vom Typ NUMBER, du vergleichst
sie aber mit dem Ausdruck to_char(vertragsbeginn,'mm') wo definitiv keine NUMBER sondern ein CHAR rauskommt.
Eine Lösung wäre also um dein TO_CHAR noch ein TO_NUMBER aussen herum zupacken, wobei das technisch korrekt aber
nicht wirklich schön wäre. Besser wärs hier die Funktion EXTRACT zu nutzen:
http://download-uk.oracle.com/docs/cd/B19306_01/server.102/b14200/functions050.htm

SQL:
IF EXTRACT( MONTH FROM vertragsbeginn ) = monat THEN
 ...
END IF;

---------
OT:

Übrigens ist heute die 19. deutsche Oracle Anwenderkonferenz in Mannheim zu Ende gegangen. Waren viele spannende Vorträge dabei. Mal schauen ob sich ein Thema findet, dass sich auch wieder für ein Tutorial eignet...
 
Zuletzt bearbeitet von einem Moderator:
Da fehlt nicht nur ein ; hinter dem END IF. Ein Blick in die Dokumentation hätte enthüllt, dass es nicht ELSEIF sondern ELSIF heißen muß.
 
Sorry für diese Nachlässigkeit. Ich hatte mir die Befehle bei Wikipedia rausgezogen und als alter Java Programmierer natürlich nur auf den Befehl geschaut und nicht auf die Schreibweise... also na klar war es elsif!
Dass mit den Konvertierungen hat mir sehr weitergeholfen. Die Datenbank läuft bei ca. 5000 Datensätzen vom gefühl her schneller. Also Danke nochmal. Wenn man es nicht besser weiß, passieren solche Fehler!
Ihr seid Spitze!
 

Neue Beiträge

Zurück