-
Probleme mit EXECUTE ROLLBACK in embedded SQL
Hallo zusammen,
ich habe das Problem dass der Execute ROLLBACK zwar ausgeführt wird (also der Satz ist als ROLLBACK markiert, aber er ist nicht tatsächlich ausgeführt. Erst wenn ich mich abmelde wird er tatsächlich ausgeführt.
Meine erste Variante war folgendes
In iSql befindet sich ein INSERT
c/exec sql
c+ Set Option Commit = *CHG
c/end-exec
c/exec sql
c+ Execute Immediate :iSql
c/end-exec
c/exec sql
c+ Execute rollback
c/end-exec
Das Programm SQLRPGLE wird mit *inlr = *on beendet
In diesem Ablauf ist das Verhalten wie ich es bereits beschrieben habe. Der Satz ist markiert (Ich kann über UPDDTA keine Änderungen an dem Satz machen) aber der Satz ist immer noch in der Datei. Erst wenn ich mich abmelde ist der Satz wieder weg.
Jetzt habe ich in den H-Bestimmungen folgendes angegeben (vorher hatte ich nichts angegeben)
h dftactgrp(*no) actgrp(*new)
Wenn ich jetzt das RPG aufrufe, wird der ROLLBACK überhaupt nicht ausgeführt. Selbst nach dem Abmelden bleibt der Satz in der Datei.
HILFE!!!!!!!! :-) Ich bin mit meinem Latein am Ende.
Ich denke ich kann es umgehen wenn ich mit STRCMTCTL und rpg commit und rollback arbeite, aber es sollte doch auch mit dem SQL Commit und Rollback möglich sein
-
Commit und Rollback werden OHNE EXECUTE aufgerufen!
Code:
EXEC SQL COMMIT;
EXEC SQL ROLLBACK;
Execute wird nur in Verbindung mit dynamischem SQL verwendet und zwar um einen mit PREPARE in ein ausführbares SQL Statement konvertierten String auszuführen.
Die Änderung wurde bei Dir nicht festgeschrieben, also es ist kein COMMIT erfolgt. Beim Abmelden wird auf Nummer Sicher gegangen, d.h. alle nicht festgeschriebenen und unter Commit ausgeführten Änderungen werden zurückgesetzt (ROLLBACK).
Du solltest außerdem nach JEDEM SQL Statement (also nach dem EXEC SQL) entweder den SQLCODE oder SQLSTATE prüfen.
Wenn der SQLCODE < 0 ist oder die ersten beiden Stellen des SQLSTATEs weder 00, noch 01, noch 02 ist, liegt ein Fehler for.
Dokumentation für die SQLCODEs und/oder SQLSTATEs sind hier:
SQL Message Finder
-
Da macht es auch schon mal Sinn, den Compiler-Output zu betrachtet, da ein "execute commit" z.B. protokolliert, dass die Variable Commit nicht zur Verfügung steht.
Oder auch, wie Birgitta schon schreibt, nach dem Execute Rollback/Commit den SQLCODE/SQLSTATE auszuwerten, da dieser hier nie erfolgreich sein kann.
-
Zitat von harkne
Hallo zusammen,
ich habe das Problem dass der Execute ROLLBACK zwar ausgeführt wird (also der Satz ist als ROLLBACK markiert, aber er ist nicht tatsächlich ausgeführt. Erst wenn ich mich abmelde wird er tatsächlich ausgeführt.
Meine erste Variante war folgendes
In iSql befindet sich ein INSERT
c/exec sql
c+ Set Option Commit = *CHG
c/end-exec
c/exec sql
c+ Execute Immediate :iSql
c/end-exec
c/exec sql
c+ Execute rollback
c/end-exec
Das Programm SQLRPGLE wird mit *inlr = *on beendet
In diesem Ablauf ist das Verhalten wie ich es bereits beschrieben habe. Der Satz ist markiert (Ich kann über UPDDTA keine Änderungen an dem Satz machen) aber der Satz ist immer noch in der Datei. Erst wenn ich mich abmelde ist der Satz wieder weg.
Jetzt habe ich in den H-Bestimmungen folgendes angegeben (vorher hatte ich nichts angegeben)
h dftactgrp(*no) actgrp(*new)
Wenn ich jetzt das RPG aufrufe, wird der ROLLBACK überhaupt nicht ausgeführt. Selbst nach dem Abmelden bleibt der Satz in der Datei.
HILFE!!!!!!!! :-) Ich bin mit meinem Latein am Ende.
Ich denke ich kann es umgehen wenn ich mit STRCMTCTL und rpg commit und rollback arbeite, aber es sollte doch auch mit dem SQL Commit und Rollback möglich sein
... da ist ja allerhand krumm!
- commit *change ist default - es sei denn, irgendein Dilletatamt hat den default geändert.
- nach ausführen eines SQL Statements einen nicht bedingten Rollback machen zu wollen, macht keinerlei Sinn.
- einen Satz löschen macht man nicht mit execute immediate, sondern mit exec sql delete...
- SQL und ACTGRP *new unter commit ist selten eine gute Idee.
Was immer Du vorhast, das was Du da versuchst, ist bestenfalls die zweitbeste Idee.
D*B
-
Ok, vielen Dank. Werde ich gleich ändern.
-
Naja, ich versuche einfach eine bestimmte Anzahl Sätze von einer Datei in eine andere Datei zu schreiben und die Sätze dann in der Ursprungsdatei zu löschen. (Archivieren).
@Bender
nicht bedingter rollback. --> Was ist ein nicht bedingter Rollback? Ich verschiebe Sätze von Datei A nach Datei B und im Anschluß mache ich einen COMMIT. Falls ein Fehler auftritt einen ROLLBACK. Was soll ich da bedingen?
- einen Satz löschen macht man nicht mit execute immediate --> Warum? Was ist der Unterschied. Wie gesagt ich lösche mehrere Sätze und schreibe mehrere Sätze
- SQL und ACTGRP * new unter commit ist selten eine gute Idee. -> warum? Das Startprogramm macht *new und in diesem Fall ist es nur das eine Programm und die folgenden *caller. Wo gibt es Probleme damit bei commit?
bestenfalls die zweitbeste Idee --> Ich bin für die beste Idee offen :-)
-
Zitat von harkne
Naja, ich versuche einfach eine bestimmte Anzahl Sätze von einer Datei in eine andere Datei zu schreiben und die Sätze dann in der Ursprungsdatei zu löschen. (Archivieren).
@Bender
nicht bedingter rollback. --> Was ist ein nicht bedingter Rollback? Ich verschiebe Sätze von Datei A nach Datei B und im Anschluß mache ich einen COMMIT. Falls ein Fehler auftritt einen ROLLBACK. Was soll ich da bedingen?
- einen Satz löschen macht man nicht mit execute immediate --> Warum? Was ist der Unterschied. Wie gesagt ich lösche mehrere Sätze und schreibe mehrere Sätze
- SQL und ACTGRP * new unter commit ist selten eine gute Idee. -> warum? Das Startprogramm macht *new und in diesem Fall ist es nur das eine Programm und die folgenden *caller. Wo gibt es Probleme damit bei commit?
bestenfalls die zweitbeste Idee --> Ich bin für die beste Idee offen :-)
... in deinem snippet war nicht erkennbar, dass du den rollback versuchst, wenn es nicht geklappt hat.
- execute iimmediate prüft erst zur runtime, insert, delete etc. rpüft bereits zur compiletime und bietet im Fehlerfall mehr Information.
- ENDJOB schickt beim Jobende ein Rollback hinterher, der alle offenen Transaktionen abräumt. ENDACTGRP schickt im default ein COMMIT hinterher, der offene Transaktionen festschreibt (auch bei IBM gibt es Dilletanten).
Gute Lösungen sind immer nebenwirkungsfrei. Das fängt damit an, dass das schreiben in eine andere Datei in der Herkunftsdatei nichts sperrt und damit der folgende delete andere Sätze löschen könnte, als vorher archiviert wurden.
D*B
-
ACTGRP *NEW verwende ich allerdings auch und vor allem bei Aufrufen aus Menüs heraus (mit einem Wrapper), da viele Programme unter ILE und SQL zu viel Müll hinter sich lassen. *NEW räumt damit halt auf.
Den execute immediate vermeide ich so gut es irgend geht da man häufig die Dynamik gar nicht benötigt.
Deine Archivierung lässt sich genauso einfach mit 2 SQL's erledigen:
exec sql insert into .... select ... from .... where...;
exec sql delete from .... where ....;
Ich denke nicht, dass sich die Where-Klausel, also die Definitition und nicht die Parameterwerte, jedes mal ändern.
Und wenn du denkst, der insert benötigt mehr Informationen als in der Quelle vorhanden, kann man diese ja im Select kalkulieren. Außerdem ist es nicht verboten im Select Parameter zu verwenden.
-
Zitat von Fuerchau
ACTGRP *NEW verwende ich allerdings auch und vor allem bei Aufrufen aus Menüs heraus (mit einem Wrapper), da viele Programme unter ILE und SQL zu viel Müll hinter sich lassen. *NEW räumt damit halt auf.
Den execute immediate vermeide ich so gut es irgend geht da man häufig die Dynamik gar nicht benötigt.
Deine Archivierung lässt sich genauso einfach mit 2 SQL's erledigen:
exec sql insert into .... select ... from .... where...;
exec sql delete from .... where ....;
Ich denke nicht, dass sich die Where-Klausel, also die Definitition und nicht die Parameterwerte, jedes mal ändern.
Und wenn du denkst, der insert benötigt mehr Informationen als in der Quelle vorhanden, kann man diese ja im Select kalkulieren. Außerdem ist es nicht verboten im Select Parameter zu verwenden.
... wenn zwischen dem insert select und dem delete noch Sätze mit deiner Bedingung hinzukommen, gelöscht werden oder sich ändern, stimmen die Sätze nicht überein!!! Und "das kann nicht passieren" ist eine beliebte Fehlerquelle.
D*B
-
-
Ja, ich habe jetzt umgestellt auf exec sql insert und delete
Ich kopiere die Daten von der Quelldatei die älter als eine Jahr sind in die Archivdatei
Im Anschluß lösche ich alle Sätze aus der Quelldatei, die sich in der Archivdatei befinden (ID). Somit sollten keine Sätze gelöscht werden, die nicht auch in der Archivdatei sind.
Similar Threads
-
By steffenboehme in forum NEWSboard Programmierung
Antworten: 7
Letzter Beitrag: 18-06-21, 09:42
-
By wti in forum NEWSboard Programmierung
Antworten: 4
Letzter Beitrag: 14-05-17, 13:13
-
By Tobse77 in forum NEWSboard Programmierung
Antworten: 9
Letzter Beitrag: 17-08-16, 08:20
-
By a.wojcik in forum NEWSboard Programmierung
Antworten: 3
Letzter Beitrag: 18-07-16, 09:54
-
By max40 in forum NEWSboard Java
Antworten: 19
Letzter Beitrag: 20-02-15, 17:39
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- You may not post attachments
- You may not edit your posts
-
Foren-Regeln
|
Erweiterte Foren Suche
Google Foren Suche
Forum & Artikel Update eMail
AS/400 / IBM i
Server Expert Gruppen
Unternehmens IT
|
Kategorien online Artikel
- Big Data, Analytics, BI, MIS
- Cloud, Social Media, Devices
- DMS, Archivierung, Druck
- ERP + Add-ons, Business Software
- Hochverfügbarkeit
- Human Resources, Personal
- IBM Announcements
- IT-Karikaturen
- Leitartikel
- Load`n`go
- Messen, Veranstaltungen
- NEWSolutions Dossiers
- Programmierung
- Security
- Software Development + Change Mgmt.
- Solutions & Provider
- Speicher – Storage
- Strategische Berichte
- Systemmanagement
- Tools, Hot-Tips
Auf dem Laufenden bleiben
|
Bookmarks