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:
- Exakte zeitliche Abgrenzung mit “Gültig ab” und “Gültig bis”
- 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-Tabelle
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:
- Lies alle Einträge, deren Gültigkeit kleiner gleich dem gewünschten Datum ist.
- Sortiere die Einträge nach GUELTIG_AB absteigend, so dass der aktuellste Eintrag an erster Stelle steht
- 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 ).
- 7. December: Excel Racing Simulation – Root Vole Race - 7. Dezember 2024
- 5. December: ABAPConf - 5. Dezember 2024
- 4. December: Only a lazy developer is a good developer - 4. Dezember 2024
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 1 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
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!
Update: Ist das gültig? (2)