Schleife zur Erstellung neuer Datensätze

CatorCanulis

Neuer Benutzer
Beiträge
2
Hallo zusammen,

ich arbeite in einem Untersuchungslabor, dass seine Proben für künftige Perioden (meistens Messjahre = Kalenderjahre) voranmeldet.

Bei der Planung der Beprobungen entstehen derartige Datensätze.

ID | MESSSTELLE | BEPROBUNGSSTART | BEPROBUNGSINTERVALL | BEPROBUNGSDATUM | …
1 | Amazonas | 04.01.2020 | 14 | 04.01.2020 | …

Die Beprobungen verlaufen in regelmäßigen Abständen (oben in einem Intervall von 14 Tagen). Der nächste Datensatz würde daher also folgendermaßen aussehen:

ID | MESSSTELLE | BEPROBUNGSSTART | BEPROBUNGSINTERVALL | BEPROBUNGSDATUM | …
1 | Amazonas | 04.01.2020 | 14 | 04.01.2020 | …
2 | Amazonas | 04.01.2020 | 14 | 18.01.2020 | …

Auf das ganze Jahr 2020 dann so:

ID | MESSSTELLE | BEPROBUNGSSTART | BEPROBUNGSINTERVALL | BEPROBUNGSDATUM | …
1 | Amazonas | 04.01.2020 | 14 | 04.01.2020 | …
2 | Amazonas | 04.01.2020 | 14 | 18.01.2020 | …

25 | Amazonas | 04.01.2020 | 14 | 05.12.2020 | …
26 | Amazonas | 04.01.2020 | 14 | 19.12.2020 | …

Schon nicht mehr dazugehören sollte: 27 | Amazonas | 04.01.2020 | 14 | 02.01.2021 | …, da dieser Datensatz bereits ein BEPROBUNGSDATUM des Folgejahres hätte.

Bislang habe ich aber nur Datensätze zu den ersten Beprobungen für jede MESSSTELLE. Gibt es eine Möglichkeit, Datensätze jahresfüllend für alle MESSSTELLEn zu generieren?

In anderen Programmiersprachen könnte das etwa so aussehen:
while (sampling_date < following_year) {
list_of_samples.add(…)
}

Wie ich Schleifen in Oracle SQL effektiv für diesen Zweck einsetzen kann, verstehe ich leider nicht.

Server-Version ist 12g.

Viele Grüße und besten Dank
Markus
 
Werbung:
Eine Schleife brauchst Du dazu nicht unbedingt, auch wenn es mit Oracle und einer StoredProcedure möglich wäre.

Das Verfahen zum Einfügen einer bestimmter Menge Datensätze sieht so aus:
insert into <table> (<fieldlist>)
select <fieldlist> from <othertable or complex statement>

Der Insert Teil dürfte klar sein, weil Du wahrscheinlich die Spaltennamen, die Du im Voraus ausfüllen willst, genau kennst.
Etwas fragwürdig wäre die ID, die evtl. automatisch angelegt wird oder nicht, entsprechend weglassen oder mit generieren.

Das Select Statement muss nun berechnete Daten liefern, die zu Deinem Bedarf passen. Ein guter Ausgangspunkt wäre sowas:
select kw_nummer + <offsetnachBedarf> from
(SELECT LEVEL kw_nummer
FROM dual
CONNECT BY LEVEL <= 43)) x

Dann statischer Wert für die Messstelle, z.B. 'Amazonas', das Startdatum to_char('04.01.2020', 'dd.mm.yyyy'), <Beprobungsintervall>
usw.
Am Intervall sieht man, dass man die generierten Werte abhängig vom Intervall und dem resultierenden Datum anpassen muss. Im Beispiel oben 43 passt zu einem wöchtenlichen Intervall und den restlichen Kalenderwochen für dieses Jahr. Entsprechend halbieren für doppelte Intervalllänge usw.
Aus der KW kann man auch das Datum errechnen und immer weiter aufaddieren.

Wenn Du noch Probleme hast, melde Dich.
 
Hallo dabadepdu,

vielen Dank!

insert into in die selbe Tabelle klingt schon mal sinnvoll. Allerdings habe ich Probleme mit dem statement:
(SELECT LEVEL kw_nummer
FROM dual
CONNECT BY LEVEL <= 43)) x

Warum 43 (das Jahr hat ja 52 Wochen) und was bedeutet hier "x"?

Das Statement liefert mir halt Zahlen von 1 bis 43. Aber wie ich daraus auf die geplanten Entnahmedaten komme erschließt sich mir leider gar nicht.

Der Index wird in der Tat automatisch generiert, siehe folgende Tabellen-Definition:

/* Erstelle eine neue Tabelle mit virtuellen Proben */
CREATE TABLE
"VIRTUAL_SAMPLE" -- Tablle für geplante Proben.
(
VIRTUAL_SAMPLE_NO NUMBER(8) GENERATED BY DEFAULT AS IDENTITY
, GCODE VARCHAR2(40 CHAR) NOT NULL
, MEDIUM VARCHAR2(40 CHAR) NOT NULL
, PROBEART VARCHAR2(40 CHAR) NOT NULL
, STARTDATUM DATE NOT NULL
, FREQUENZ NUMBER(3) NOT NULL
, SAMPLING_DATE DATE NOT NULL
/* Alle Felder oberhalb müssen in Kombination
eindeutig sein. */
, PRIMARY KEY(VIRTUAL_SAMPLE_NO)
, CONSTRAINT MMPZ UNIQUE (
GCODE
, MEDIUM
, PROBEART
, STARTDATUM
, FREQUENZ
)
);

Dabei ist der GCODE eine bekannte Kodierung für eine Messstelle (im Beispiel "Amazonas") und SAMPLING_DATE ist das geplante Entnahmedatum, dass wir gerade versuchen, zu bestimmen. Die Constraint soll sicherstellen, dass es immer nur eine "virtuelle" Probe zu einem gegebenen Zeitpunkt gibt. Man kann ja nur z.B. eine Stich-Probe (ist die Probeart / Art der Probenahme) am 25. Mai (SAMPLING_DATE) aus dem Flusswasser (MEDIUM) des Amazonas (GCODE) ziehen.
 
Werbung:
was bedeutet hier "x"?
x ist ein Alias für das Selectstatement das in Klammern dort steht. Ich habe es in den folgenden Beispielen xyz getauft, man kann nehmen, was man will. Besser man nimmt etwas sinnvolles, kurzes, verständliches, das keiner Oracle Funktion oder Schlüsselwort entspricht.

Hier sind ein paar Beispiel, hoffentlich siehst Du jetzt klarer. Das Feld "kw_nummer" könnte man auch anders nennen, hier in den Beispiel, wo es meist für einen Wochentag steht, ist es ein unpassender Name. Aber ich habe es stehen lassen, weil es im Kern der Wert ist, aus dem Du Deine Kalenderwochen bastelst - mit etwas Mathe.

Code:
select kw_nummer, kw_nummer + 0 as EinWochentagMitOffset0 from
(SELECT LEVEL kw_nummer
FROM dual
CONNECT BY LEVEL <= 7) xyz;

select kw_nummer, to_date('21.01.2021','DD.MM.YYYY')+kw_nummer as SiebenTageImJanuar from
(SELECT LEVEL kw_nummer
FROM dual
CONNECT BY LEVEL <= 7) xyz;


select kw_nummer, sysdate+kw_nummer  as SiebenTageAbJetzt from
(SELECT LEVEL kw_nummer
FROM dual
CONNECT BY LEVEL <= 7) xyz;


select kw_nummer, sysdate+(kw_nummer*14)  as Sieben14TageIntervalle from
(SELECT LEVEL kw_nummer
FROM dual
CONNECT BY LEVEL <= 7) xyz;
 
Zurück
Oben