Ist das gültig?

Das fragt man sich als Programmierer häufig. Speziell dann, wenn man aus zeitlich abgegrenzten Datensätzen den richtigen Datensatz herausfinden muss. Hier zeige ich dir, wie man einfach aber sicher ans Ziel kommt.

Gültigkeitszeitraum vs. Gültig ab

Wenn Datensätze zeitlich voneinander abgegrenzt werden sollen, hat man in der Regel die folgenden zwei Möglichkeiten:

  1. Exakte zeitliche Abgrenzung mit “Gültig ab” und “Gültig bis”
  2. Abgrenzung mit “Gültig ab”

Bei Variante (1) hat man den Vorteil, dass man einen Zeitraum auch “schließen” kann. Beziehungsweise im Umkehrschluss: Man muss den Zeitraum auch begrenzen. Anders bei Variante (2): Hier gibt es immer einen gültigen Eintrag (sofern mindestens ein Eintrag vorhanden ist).

Der große Nachteil bei Variante (1) ist ebenfalls, dass eine exakte zeitliche Abgrenzung schwer zu administrieren und zu programmieren ist. Besonders dann, wenn Zeiträume in einen oder zwei vorhandene Zeiträume eingefügt werden sollen. Hier ist Variante (2) deutlich einfacher und pflegeleichter.

Variante (2) eignet sich also besonders dann sehr gut, wenn zu einem “Objekt” immer ein gültiger Eintrag vorhanden sein soll. Deshalb werden wir uns diese Variante genauer ansehen.

Gültig ab-Tabelle2016-12-01_14-51-58

Als einfaches Beispiel habe ich mir eine Tabelle erstellt, die ein Gültig-Ab-Datum und eine Monatsbezeichnung hat. Es kann also für jedes Datum eine Bezeichnung vergeben werden.

Diese Tabelle ist zugegebener Weise einigermaßen Sinn frei, verdeutlicht aber sehr gut das Verfahren.

Ermittlung des gültigen Eintrags – herkömmlich

Um aus der vorgestellten Tabelle zu einem Datum den jeweils gültigen Eintrag zu lesen, geht man normalerweise folgendermaßen vor:

  1. Lies alle Einträge, deren Gültigkeit kleiner gleich dem gewünschten Datum ist.
  2. Sortiere die Einträge nach GUELTIG_AB absteigend, so dass der aktuellste Eintrag an erster Stelle steht
  3. Lies den Eintrag an erster Stelle
SELECT * FROM ztt_datum INTO TABLE lt_datum 
 WHERE gueltig_ab <= mein_datum
 ORDER BY gueltig_ab DESCENDING.
READ TABLE lt_datum INTO DATA(ls_datum) INDEX 1.

Der Nachteil von dieser Variante ist, dass man alle jemals gültig gewesenen Einträge lesen muss.

Ermittlung des gültigen Eintrags – Tricktresor-Style

Mithilfe eines Subqueries ist es möglich, exakt den einen richtigen Eintrag zu finden. Ein Code-Snippet sagt mehr als tausend Worte:

SELECT single * FROM ztt_datum INTO @DATA(ls_datum)
 WHERE datab = ( SELECT MAX( datab )
                   FROM ztt_datum
                  WHERE datab <= @p_datum ).

Enno Wulff

COMMENTS

  • <cite class="fn">abapkadabra</cite>

    Moin Enno,

    ich bin ja überhaupt kein Freund von SELECT…ENDSELECT, finde aber in diesem Fall folgendes Coding lesbarer und damit auch besser wartbar:

    SELECT FROM ztt_datum
      UP TO ROWS
      INTO ls_datum
      WHERE gueltig_ab <= p_datum
      ORDER BY gueltig_ab DESCENDING.
    ENDSELECT.

    Oder gibt es Argumente, die dagegen sprechen würden?

    Grüße, Ingo

    • <cite class="fn">Enno Wulff</cite>

      Nein. In dem Fall funktioniert es. Das stimmt. Ich glaube, ich habe in diesem Fall mein Beispiel zu viel vereinfacht. Ich prüfe das noch mal.

      Es ist nämlich dann nicht mehr trivial, wenn du nicht nur EINEN Eintrag benötigst sondern zu einer Gruppe von Werten den jeweils zuletzt gültigen.
      Dann passt mein toller Hinweis mit dem SELECT SINGLE aber auch nicht mehr.

      Danke für deinen Hinweis!

Comments are closed.