PDA

View Full Version : Nur bestimmte Felder bei WRITE in PF schreiben



Seiten : [1] 2

harkne
05-08-20, 16:07
Hallo zusammen,

ich habe folgendes Problem.
Ich habe mehrere Dateien in die ich schreibe oder update.
Alle Dateien sind unter COMMIT
Bei der einen Datei habe ich jetzt das Problem das ich nur 4 Felder von 10 füllen soll und da ich ja aber beim RPG-Write immer alle Felder angebe, werden die Default-Werte der Felder (Datei ist über SQL erstellt) nicht gezogen.

Jetzt habe ich halt 2 Lösungswege die ich bisher noch nicht hatte.

1. Ich schreibe nur die 4 Felder wenn es da eine Möglichkeit gibt wie bei update %fields, denn write %fields geht ja nicht.

2. Ich mache einen INSERT INTO (also SQL im RPG) da weiß ich aber nicht ob der COMMIT und gegebenenfalls der ROLBK auch den Satz mit SQL wieder zurück nimmt.

Kann mir da jemand was dazu sagen ?

Viele Grüße Harald

Fuerchau
05-08-20, 21:19
Für Commit-Steuerung ist die Art native oder SQL nicht relevant.
Native gibts die Option der F-Bestimmung (oder DCL-F) für Commit, bei SQL bestimmt es Set Option.
Wenn dies gewährleistet ist, kannst du beliebig mischen.

Für deinen partiellen Insert gibt es noch eine einfache Kontrolle:

exec sql select * into : MyDs from final table (insert into MyTable (F1.....) values(: F1.....));

D.h., du kannst nach dem Insert die Daten direkt ohne Schlüssel wieder auslesen um sie weiter zu verwenden. Dabei werden Defaults ebenso zurückgegeben wie Identity-Spalten, Timestamps oder Functions. Ggf. musst du noch ein NullFlag-Array beim Into angeben.

harkne
05-08-20, 23:03
Für Commit-Steuerung ist die Art native oder SQL nicht relevant.
Native gibts die Option der F-Bestimmung (oder DCL-F) für Commit, bei SQL bestimmt es Set Option.
Wenn dies gewährleistet ist, kannst du beliebig mischen.

Für deinen partiellen Insert gibt es noch eine einfache Kontrolle:

exec sql select * into : MyDs from final table (insert into MyTable (F1.....) values(: F1.....));

D.h., du kannst nach dem Insert die Daten direkt ohne Schlüssel wieder auslesen um sie weiter zu verwenden. Dabei werden Defaults ebenso zurückgegeben wie Identity-Spalten, Timestamps oder Functions. Ggf. musst du noch ein NullFlag-Array beim Into angeben.

Beim oberen Teil heißt dass, ich kann im RPG einen ROLBK machen und sowohl die im RPG mit WRITE geschriebenen Sätze als auch der Satz der mit SQL-INSERT eingefügt wurde, werden wieder zurück genommen

Was den unteren Teil betrifft entzieht sich mir hier das Verständnis auf meine Frage. Wie ich einen INSERT mit nur ein paar Feldern mache, das weiß ich, wichtig wäre es für mich gewesen, zu wissen, ob es auch ohne SQL eine Möglichkeit im RPG gibt einen WRITE zu machen und dabei nur bestimmte Felder anzugeben, eben wie bei UPDATE %fields.

B.Hauser
06-08-20, 09:22
Wichtig wäre es für mich gewesen, zu wissen, ob es auch ohne SQL eine Möglichkeit im RPG gibt einen WRITE zu machen und dabei nur bestimmte Felder anzugeben, eben wie bei UPDATE %fields.

Du kannst eine logische Datei (oder besser einen SQL Index) mit Feld-Auswahl anlegen und dann den RPG Write in diese logische Datei/Index machen. Für die übrigen Felder sollten dann die Default-Werte gezogen werden.
... ich würde trotzdem SQL vorziehen ;)

Birgitta

harkne
06-08-20, 23:22
Vielen Dank für die Antworten, ich habe jetzt den INSERT über SQL gemacht. Vorher SET COMMIT = *CHG und Commit und Rolbk funktionieren

Fuerchau
07-08-20, 07:43
Zum Verständnis des "Select * from final table (insert ...)":
Dieser Select liest das Ergebnis, dass durch den Insert erstellt wird.
Dadurch erhältst du eben auch alle Defaults und ggf. durch Trigger geänderte Werte.
Dies macht auch Sinn um z.B. vom System vergebene Identity-Werte auszulesen.
Die SQL-Funktion "IDENTITY_VAL_LOCAL()" ist potentiell unsicher, da durch Prozeduren (Trigger, Default-Functions) ebenso Identities gesetzt werden können und du somit nur die letzte Identity bekommst, die aber nicht von deinem Insert stammen muss.

ExAzubi
10-08-20, 12:03
Datenstruktur über die Datei legen, Renamen, DS initialisieren, füllen und diese dann In die Dateifelder schieben, oder aber eine weitere DS über die Tabelle legen und die 1- DS in die andere DS moveln...

Fuerchau
10-08-20, 13:25
@ExAzubi:
In diesem Fall streiche da eher das "Ex" aus deinem Namen;-).

Wenn die Datei durch die F-Bestimmung komplett alle Felder beinhaltet, wird sie von RPG auch automtisch komplett verarbeitet.
Hintergrund:
Die F-Bestimmung verwendet intern einen File-Control-Block (FCB), der einen Satzpuffer über die gesamte Länge enthält.
Auf diesen Satzpuffer verweist eine interne DS mit allen Feldern, die der Compiler kennt.
Solange du nur I- und O-Bestimmungen hast, sind in RPG nur die verwendeten Felder verfügbar.
Wenn du eine "E DS" erstellst (bzw. eine Compiler-Option), dann eben alle Felder dieser DS.
Beim READ/CHAIN wird aus dem Satzpuffer in die Felder übertragen, beim Update nur die verwendeten oder in ILE die angegebenen Felder.
Ist die Datei zum Anfügen geöffnet, werden beim Write wieder alle Felder verwendet. Hierbei werden keinerleid Defaults aus SQL/DDS gezogen!

Defaults der DDS sind nur für DSPF's gültig, Defaults aus SQL werden da ignoriert.

In SQL gibt es noch eine Schicht vor der DB-Schicht (also dem FCB), so dass beim Insert nicht erwähnte Felder mit ihrem Default in den Puffer geschrieben werden können bevor er in die Tabelle geschrieben wird.

ExAzubi
10-08-20, 14:47
@Fuerchau
Das tut weh ;) ;-)

Soweit ich weiß geht das aber nur, wenn die Datei IF A oder UF A in den F-Karten definiert ist. Sobald eine Datei als O definiert ist, ist die INPUT DS nicht vorhanden und somit werden die Felder auch nicht initialisiert, wenn die Datei geöffnet wird?!?!? Aber ich kann ich auch irren...

Fuerchau
10-08-20, 16:46
Ich sagte ja I-Bestimmungen und O-Bestimmungen.
Diese werden auf Grund der F-Bestimmungen und Feldverwendungen automatisch generiert.
Daher gibts ja auch beim Append (Write) ohne Initialisierung bei späteren Reads die Laufzeitfehler über die man sich dann wundert.

Ausnahme nun Fully-Free, denn da muss ich ja mit DS'n arbeiten.
Versuche da mal eine DS zu verwenden, die nicht der Datei entspricht, da die DS mit *LIKEREC definiert werden muss sonst ist sie ja nicht verwendungsfähig.