Anmelden

View Full Version : Veränderungsprotokoll über RCVJRNE



Seiten : [1] 2

Ottersberg
07-06-11, 10:58
Moin,

kurze Beschreibung des Vorhabens:
Über RCVJRNE wollen wir ein Exit-PGM an das Journal hängen.
Wir wollen dadurch Änderungen an Datensätzen mitbekommen und eine Art Protokoll erstellen, sprich "Wann wurde der Datensatz angelegt", "Wann hat wer welche Veränderungen vorgenommen", "Wann wurde der Datensatz gelöscht".
Das ganze für den "normalen" Benutzer über die Standard Journal-Funktion hinaus.
Außerdem soll das für mehrere Dateien gelten und idealerweise wollen wir nicht für jede Datei ein eigenes Programm erstellen.

Was ich bislang hinbekommen habe:
(Besser wusste ich es nicht. Vorschläge wie man es besser macht höre ich gerne.)


Exit-PGM, welches die Journaldaten erhält.
Exit-PGM ruft Programm auf, welches über SQL eine Tabelle erstellt wie die Datei aus den Journaldaten, um die Dateifelder zu erhalten. (Die Datei erhält lvlchk *no wegen der nachfolgenden Programme)
Exit-PGM ruft Programm auf und übergibt Journaldaten. Daten werden über das aufgerufene Programm in die per SQL erstellte Tabelle geschrieben.
Exit-PGM ruft bei Update Programm auf, welche die Datensätze 1 (UB) und 2 (UP) aus der per SQL erstellten Tabelle ausliest, in Datenstrukturen (likerec der Tabelle) packt und die Datenstrukturen vergleicht. So weiß ich, ob überhaupt eine Veränderung stattgefunden hat.


Jetzt zum Problem:
Per SQL komme ich zwar, über syscolumns, an die Spaltennamen und die Anzahl der Spalten, aber mir fällt nichts ein wie ich diese Spaltennamen dann einzeln abfragen kann auf Veränderung.
Eine Datenstruktur (likerec der Tabelle) wird zwar korrekt gefüllt, aber ich kann die einzelnen Felder der Datenstruktur nicht abfragen, da ich den Namen nicht weiß. Oder kann man die Felder auch über Nummern abfragen? Quasi anstatt Datenstruktur.Feldname1 Datenstruktur.Feldnummer1?
Oder sonst Ideen wie ich weitermachen könnte?

Gruß

Fuerchau
07-06-11, 12:50
Da hilft nur ein bisschen Arbeit:
Per SYSCOLUMNS kannst du dir zu den Namen die relative Position und Typen ja abfragen.
Jetzt führst du nur eine Tabelle mit den Namen und der rel. Adresse in der DS.
Dann kannst du per %subst(MyDs:Pos:Len) über den Namen extrahieren und verarbeiten.
Gepackte Daten würde ich in eine HilfsDS packen:

D NumDS ds
D NumFld 31p 0

d HelpDS DS
d HelpNum 31p 0 inz
d HelpX 15 overlay(HelpNum)

evalr NumDs = HelpX + %subst(MyDs:Pos:Len)

Pikachu
07-06-11, 12:50
Wir wollen dadurch Änderungen an Datensätzen mitbekommen und eine Art Protokoll erstellen, sprich "Wann wurde der Datensatz angelegt", "Wann hat wer welche Veränderungen vorgenommen", "Wann wurde der Datensatz gelöscht".
Sind für sowas Trigger denn nicht besser geeignet?

Robi
07-06-11, 12:54
Ich mach das anders ...
ich ermittel die Start und Ende Position jedes Feldes aus der Datei.
somit habe ich feldname, start und ende.
mit einem srvpgm bekomme ich den geänderten Feldnamen und die 'bis' position
Dann bilde ich einen String, Feldname: alter Inhalt : neuer inhalt, |
bis 204 Spalten voll sind(nicht mehr reichen) 204 weil mehr der Drucker nicht kann und für bestimmte Dateien wird das gedruckt und abgezeichnet)
dann druck und nächste Zeile
alles in allem, 3-4 Programme für jede Dateien anwendbar.

(verkürzte theoretische Darstellung, da unser Entw. System einige Besonderheiten mittbringt und ich z.B. die Spaltenfolge nicht via
QADBILFI ermitteln brauche)

Gruß
Robi

jetzt waren doch andere schneller ...
@Pikachu
Jain, wenn du es nicht je Datei machen willst ist das schon so ok.
sonst hättest du je Datei einen trigger, der es entweder individuell macht oder die o.a logik durchführt. Das ist nicht immer das schnellste :)

Ottersberg
07-06-11, 16:55
Da hilft nur ein bisschen Arbeit:
Per SYSCOLUMNS kannst du dir zu den Namen die relative Position und Typen ja abfragen.
Jetzt führst du nur eine Tabelle mit den Namen und der rel. Adresse in der DS.
Dann kannst du per %subst(MyDs:Pos:Len) über den Namen extrahieren und verarbeiten.

Da kann dann auch die temporäre Tabelle im Look der Tabelle lt. Journaldaten entfallen.
Das bin ich jetzt mal angegangen.


Ich mach das anders ...
ich ermittel die Start und Ende Position jedes Feldes aus der Datei.
somit habe ich feldname, start und ende.
mit einem srvpgm bekomme ich den geänderten Feldnamen und die 'bis' position
Dann bilde ich einen String, Feldname: alter Inhalt : neuer inhalt, |
bis 204 Spalten voll sind(nicht mehr reichen) 204 weil mehr der Drucker nicht kann und für bestimmte Dateien wird das gedruckt und abgezeichnet)
dann druck und nächste Zeile
alles in allem, 3-4 Programme für jede Dateien anwendbar.

Klingt eigentlich wie der Ansatz von Fuerchau. Mich würde da noch interessieren, wie du Start und Ende Position ermittelst.
Da fallen mir nur SYSCOLUMNS oder DSPFFD ein, wo ich das erste auf jeden Fall bevorzuge.

Fuerchau
07-06-11, 17:47
SYSCOLUMNS ist das einfachste und auch schnellste, wenn man mit SQL arbeitet.
DSPFFD mit Outfile ist auch einfach, wenn man keine API's verwenden möchte.
API's sind auch schnell, wenn man sich damit auskennt (USRSPC-API's kommen noch hinzu).

Wenn man sich mal per DSPFD die SYSCOLUMNS ansieht, bekommt man mit, welche Tabelle in der QSYS als Basis dient (QADB...).
Früher habe ich mittels Direktzugriff die Informationen daraus gelesen, was aber zu stark releaseabhängig ist (Levelcheck-Error).

BenderD
07-06-11, 19:42
... eigentlich ist nur relevant, wenn sich das Layout der Datei ändert, sprich: man müsste sich das cachen - führt unmittelbar dazu, dass man das Event verarbeitet, wenn sich die Datei ändert (kommt auch im Journal), was dann bedeutet, dass man sich auch ein statisches Programm generiert...


D*B

Robi
08-06-11, 10:50
Klingt eigentlich wie der Ansatz von Fuerchau. Mich würde da noch interessieren, wie du Start und Ende Position ermittelst.
Da fallen mir nur SYSCOLUMNS oder DSPFFD ein, wo ich das erste auf jeden Fall bevorzuge.

ja, das ist ähnlich
wir haben die START und ENDE Positionen in einer Datei in der wir nachschauen können. Das macht unser Entw. System automatisch.
Bei einem Kunden, der 'herkömlich' arbeitet lesen wir die
QADBILFI für die datei durch und merken alles in einer multi occur Tabelle. So haben wir nach und nach 30 Dateibeschreibungen im Zugriff.
Robi

Ottersberg
08-06-11, 12:42
Gepackte Daten würde ich in eine HilfsDS packen:

D NumDS ds
D NumFld 31p 0

d HelpDS DS
d HelpNum 31p 0 inz
d HelpX 15 overlay(HelpNum)

evalr NumDs = HelpX + %subst(MyDs:Pos:Len)

Das verstehe ich noch nicht ganz.
Als Beispiel krieg ich für ein DECIMAL-Feld (lt. syscolumns) mit length 6 und storage 4, was lt. DDS als 6P0 definiert ist, folgendes:

00000000000000000000000[]0019102

Das lässt sich nicht über %char() in einen Character umwandeln.

Fuerchau
08-06-11, 12:55
Eben deswegen die HilfsDS.
Gepackte Felder haben immer eine ungerade Anzahl Stellen, auch wenn man gerade Anzahl definiert hat.
Definiere ich nun ein Hilfsfeld von 31p 0, kann ich per %subst das Feld aus der DS rechtsbündig in das Hilfsfeld übertragen, dabei muss ich natürlich nach vorne mit X'00' auffüllen:

evalr NumDs = HelpX + %subst(MyDs:Pos:Len)

Zur Ausgabe kann ich dann per %char(NumFld) den Wert aufbereiten.