Monate zu einem Datum hinzufügen. Da gibt's doch nix zu sagen, oder doch?
Das Thema DATE und TIMESTAMP hatte ich zwar schon, aber aus gegebenem Anlaß möchte ich heute doch noch ein kurzes Posting nachschieben. Es geht darum, wie man am effizientesten Monate zu einem Datum hinzufügt oder von diesem abzieht. Die eleganteste Variante scheint die INTERVAL-Syntax zu sein ...
SQL> select to_date('2010-10-12', 'YYYY-MM-DD') - interval '1' month datum
2 from dual;
DATUM
----------
12.09.2010
1 Zeile wurde ausgewählt.
Sieht erstmal gut aus ... aber wenn man das mal mit dem 31.10. probiert, erlebt man
eine Überraschung ...
SQL> select to_date('2010-10-31', 'YYYY-MM-DD') - interval '1' month datum
2 from dual;
FEHLER in Zeile 1:
ORA-01839: Datum für angegebenen Monat nicht gültig
Was soll das? Naja, Oracle nimmt vom 31.10. einen Monat weg und kommt dann auf den 31.09. - den gibt es aber nicht, also wird ein Fehler ausgelöst. Das ist nicht so schön - aber nicht zu ändern. Es gibt zwei Möglichkeiten, mit dem Problem umzugehen. Zunächst könnte man mit dem "nächsten Ersten" arbeiten. Also nicht einen Monat vom 31.10. abziehen, sondern erstmal zum nächsten Ersten gehen (1.11.), dann den Monat abziehen und wieder zurückgehen. Das ist dann ein wenig Spielen mit TRUNC und ROUND. Alles in allem eher aufwändig.
Oder man verwendet die "alte" Funktion ADD_MONTHS. Anders als der Name vermuten lässt, kann man damit auch Monate abziehen.
SQL> select add_months(to_date('2010-10-31', 'YYYY-MM-DD'), -1) from dual;
ADD_MONTHS
----------
30.09.2010
Also: wenn es darum geht, "Monate" von einem Datum abzuziehen oder dazuzurechnen, ist ADD_MONTHS die einfachere
Variante - sie erfordert keine Sonderbehandlung für die Tage ab dem 28. eines Monats. Sogar der 29. oder der 30. können zum beschriebenen Fehler führen - wenn man nach dem Abziehen oder Hinzufügen der Monate im Februar landen würde.