[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    May 2004
    Beiträge
    444

    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

  2. #2
    Registriert seit
    Aug 2001
    Beiträge
    2.873
    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
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  3. #3
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    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.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  4. #4
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    Zitat Zitat von harkne Beitrag anzeigen
    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
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  5. #5
    Registriert seit
    May 2004
    Beiträge
    444
    Ok, vielen Dank. Werde ich gleich ändern.

  6. #6
    Registriert seit
    May 2004
    Beiträge
    444
    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 :-)

  7. #7
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    Zitat Zitat von harkne Beitrag anzeigen
    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
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  8. #8
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    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.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  9. #9
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    Zitat Zitat von Fuerchau Beitrag anzeigen
    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
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  10. #10
    Registriert seit
    May 2004
    Beiträge
    444
    Ok, super, vielen Dank

  11. #11
    Registriert seit
    May 2004
    Beiträge
    444
    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

  1. embedded SQL Cursor with Hold und Commit/Rollback
    By steffenboehme in forum NEWSboard Programmierung
    Antworten: 7
    Letzter Beitrag: 18-06-21, 09:42
  2. Commit und Rollback bzw. nicht Rollback
    By wti in forum NEWSboard Programmierung
    Antworten: 4
    Letzter Beitrag: 14-05-17, 13:13
  3. Antworten: 9
    Letzter Beitrag: 17-08-16, 08:20
  4. SQL Frage zu "execute immediate"
    By a.wojcik in forum NEWSboard Programmierung
    Antworten: 3
    Letzter Beitrag: 18-07-16, 09:54
  5. SQL Select Statement - Execute dauert sehr lange
    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
  •