[NEWSboard IBMi Forum]

Thema: SQL Update

  1. #1
    Joe is offline [professional_User]
    Registriert seit
    Mar 2001
    Beiträge
    365

    SQL Update

    Hallo Forum.

    Ein Bild sagt mehr als tausend Worte...
    deshalb etwas Code:

    D File E DS ExtName(Datei)
    D UFile E DS Extname(Datei) Prefix(U)

    C *Entry Plist
    C Parm File
    C Parm UFile

    C select
    C when Fld01 <> UFld01
    C eval Fld01 = UFld01
    C when Fld02 <> UFld02
    C eval Fld02 = UFld02
    C when Fld03 <> UFld03
    C eval Fld03 = UFld03
    C* usw.
    C endsl
    C if file <> UFile
    C update Datei
    C endif



    Dieses "Program" wird aus einer DDS
    generiert und als "Server-Program" für Datei-Updates eingesetzt.
    Der Update erfolgt nur für die tatsächlich geänderten Felder
    aus der Datei-Datenstruktur UFile.
    (Natürlich fehlt da einiges an Code- aber ich hoffe, das wesentliche kommt rüber.)
    Und Jetzt die Frage an *ALL:
    Wie kann ich den Select/Update entsprechend dem obigen Beispiel mit Embedded SQL erledigen?
    Geht das überhaupt?

    Gruss Joe

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Wenn ich mir den Code so betrachte ist das so falsch wie nur irgend möglich !!

    Was passiert denn eigentlich wenn mehr als 1 Feld geändert wird ?
    => Es wird nur das 1. geänderte Feld in die Datei geschrieben !!

    Warum ?

    Ein SELECT entspricht einem IF ... ELSE IF ... ELSE IF ... ENDIF ENDIF

    Und wozu soll das dann gut sein ?

    Ausserdem muss man zu RPG folgendes wissen:
    Die DB400 arbeitet mit einem internen Dateipuffer, der von RPG pro Feld mit einem MOVE gefüllt wird bevor die EA-Operation stattfindet. Deshalb optimiert der Compiler auf Grund der Verwendung von Feldern.
    Werden Felder nicht verwendet, findet auch keine Übertragung statt, weder beim Lesen noch beim Schreiben.

    Der Update ändert nun ALLE Felder automatisch mit, so dass eigentlich die Abfrage ob sich was geändert hat müssig ist.

    Und nun zu embedded SQL:

    Der Update sieht hierzu ganz simpel aus, da (wie oben angemerkt) kein Performance-Gewinn entsteht wenn jedes Feld einzeln geändert wird.

    UPDATE MYFILE SET F1=:UF1, F2=:UF2 ...
    WHERE KEY1=:UKEY1 and KEY2=:UKEY2 ...

    Auch hier ist es wenig sinnvoll den Update zu zerlegen, da sonst für jedes Feld ein einzelner Update erforderlch wäre.
    Auch hierzu sei zu bemerken, dass SQL intern nicht anders arbeitet als RPG: Satz lesen, Felder übertragen, Satz updaten.
    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

  3. #3
    Joe is offline [professional_User]
    Registriert seit
    Mar 2001
    Beiträge
    365
    Hallo Herr Fuerchau.

    Ich muss Ihnen absolut Recht geben, mein Beispiel ging total daneben. Natürlich kein Select(when) sondern if...
    Und ausserdem waren die DS falsch definiert.
    Deshalb hier die überarbeitete Version.

    Sinn und Zweck: Für jede Datei soll ein zentrales "GET", "UPDATE", "INSERT", "DELETE" -Programm verwendet werden.

    +++++++++++++++++++++++++++++++++++++++++++
    Irgend ein Verarbeitungsprogramm

    D PARMA E DS EXTNAME(Datei) Prefix(A)
    D PARMN E DS EXTNAME(Datei)

    C* füllen Keyfelder in "PARMA"
    C CALL "GET"
    C PARM PARMA
    C Move PARMA PARMN
    C* Verarbeitung z.B. Bildschirmausgabe von "PARMN"
    C* Ändern von Felder(n) in "PARMN"
    C* Aufrufen UPDATE-Programm
    C CALL "UPD"
    C PARM PARMA
    C PARM PARMN

    ++++++++++++++++++++++++++++++++++++++++++++++
    Programm "UPD"
    ++++++++++++++++++++++++++++++++++++++++++++++
    FDatei UF E K DISK
    D PARMA E DS EXTNAME(Datei) Prefix(A)
    D PARMN E DS EXTNAME(Datei) Prefix(N)
    C *ENTRY PLIST
    C PARM PARMA
    C PARM PARMN
    C If PARMN <> PARMA
    C Key Chain Datei
    C* jetzt stehen Fld01,Fld02... zur Verfügung
    C If NFLD01 <> AFld01
    C eval Fld01 = NFld01
    C endif
    C If NFLD02 <> AFld02
    C eval Fld02 = NFld02
    C endif
    C update Datei
    C endif

    ++++++++++++++++++++++++++++++++++++++++++++++
    Programm "GET"
    ++++++++++++++++++++++++++++++++++++++++++++++
    FDatei IF E K DISK
    D PARMA E DS EXTNAME(Datei)
    C *ENTRY PLIST
    C PARM PARMA
    C Key Chain Datei ***Keyfelder werden in PARMA übergeben
    C Return

    ++++++++++++++++++++++++++++++++++++++++++++++

    Soviel zum Programmcode.
    Der funktioniert übrigens und ist täglich im Einsatz.

    Gruss Joe


    Hallo *ALL.
    Ich weiss dass dieses Forum kein RPG-Seminar ist wie bei anderen Beiträgen schon mehrmals angemerkt wurde.
    Ich möchte nur erfahren, ob SQL die Möglichkeit bietet, innerhalb
    eines Update Feldbedingungen abzufragen um nur bestimmte
    Felder zu verändern.

    Gruss Joe

  4. #4
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    Hey Joe,

    um es mit Jimi Hendrix zu sagen, ich würde bei solchen Zugriffsprogrammen dringend zu einem ILE Serviceprogramm mit exportierten Prozeduren für update, delete und insert raten. Für die Datenbank Operationen kann man dann Record Level Access oder SQL verwenden, das gibt sich bei den Satzoperationen wenig.
    Interessant wird es bei Mengen orientierten Operationen (zum füllen eines Subfiles z.B.) da ist SQL weit im Vorteil und wesentlich flexibler, insbesondere bei der Verwendung von dynamic SQL.

    Dieter Bender

  5. #5
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    @Dieter Urlaub schon vorbei ?

    @Joe

    Ich muss noch mal auf meinen obigen Beitrag hinweisen.

    Sehr viel schneller ist das ganze, wenn man die ganzen If's einfach wegläßt und mit einer Mehrfachstruktur arbeitet (OCCURS 2) und ohne Prefix.

    Warum ?

    Vor dem Chain auf OCCURS 2 umschalten, RPG füllt automatisch alle Felder, die aber nicht verwendet werden.
    Auf OCCURS 1 zurückschalten und den Update durchführen.

    Anstelle von OCCURS kann man ja auch die gesamte Struktur übertragen.
    Ein Zeitvorteil ist Ihre Methode nicht, da ja sowieso ein Update des gesamten Immage stattfindet.

    Wie entgehst du der Gefahr des konkurierenden Updates ?!?!

    Zwischen dem CALL GET und CALL UPD kann ja einige Zeit liegen.
    Also müsstest du das aktuelle Immage (CHAIN) mit dem vorher gelesenen Immage (aus GET) vergleichen und nur wenn dieses noch gleich ist, deinen Update durchführen, ansonsten brauchst du eine Fehlerbehandlung, von wegen "Daten zwischenzeitlich geändert" oder so.

    Und nun nochmal zu SQL:

    Natürlich kannst du mittels CASE Abfragen durchführen, aber um es RPG-Like zu gestalten musst du auf jeden Fall einen SELECT vorher durchführen (analog CHAIN) um überhaupt vergleichen zu können.

    Übrigens: Ohne CMTCTL wirst du Probleme mit konkurierenden Updates erhalten, wenn du den Datensatz beim Lesen nicht sperrst (SELECT .... FOR UPDATE ............... UPDATE CURRENT OF )
    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

  6. #6
    Registriert seit
    Aug 2001
    Beiträge
    2.873

    Update mit SQL

    Hallo Joe,

    ich nehme an, dass beim GET z.Z. eine Input Datei eingelesen wird und beim Update dann die entsprechende Update Datei.

    Bei dem Update-Programm soll nur dann ein Feld fortgeschrieben werden, wenn sich die Feldwerte zwischen 1. Lesen und Fortschreiben geändet haben.
    Anderenfalls könnten zwischenzeitliche Änderungen überschrieben werden.

    Soweit so klar!

    Ich würde vorerst noch abraten das Ganze mit SQL zu machen, da der Zugriff für einen einzelnen Datensatz mit SQL länger dauert.
    Müssen mehrere Sätze eingelesen werden (z.B. Füllen einer Subfile) ist SQL die bessere Wahl.

    Im Prinzip kannst Du im SQL-genauso verfahren wie im RPG:
    1. Cursor für den SELECT definieren
    2. Cursor öffnen
    3. Den Satz mit FETCH einlesen
    2. Die Felder wie gehabt mit RPG prüfen und die Host-Variablen, die upgedated werden sollen umladen
    3. Update des eingelesenen Satzes mit
    UPDATE FILE SET Feld1 = :UpdFeld1, .... FOR CURRENT OF CursorName

    Für die Update-Routine über RPG würde ich ausserdem nicht den Schlüssel sondern die Relative Satz-Nr. übergeben.
    Damit wird sicher gestellt, dass genau der richtige Satz verarbeitet wird.
    (Bei SQL dauert das zu lange. Da kein Index über die relative Satz-Nr. erstellt werden kann, wird die komplette Datei verarbeitet)

    Weiterhin würde ich unabhängig ob mit SQL oder RPG gearbeitet wird ein Service-Programm (kein Programm) erstellen und aufrufen.
    Der Aufruf ist schneller!
    Ausserdem würde ich beim Service-Programm eine feste Activierungs-Gruppe (z.B. Aktivierungs-Gruppe=Service-Programm-Name) angeben, so dass das Service-Programm nicht für jedes Programm, das es aufruft aktiviert werden muss.

    Birgitta
    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

  7. #7
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    @Birgitta

    Bei "UPDATE ... CURRENT OF .." wird genau 1 Satz geändert, da ja der aktuelle Cursor verwedet wird.

    Bei "UPDATE ... WHERE ..." hast du natürlich Recht, wenn keine UNIQUE-Bedingung angegeben ist. Ausserdem bleibt hier noch das Problem der Satzsperre.
    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

  8. #8
    Joe is offline [professional_User]
    Registriert seit
    Mar 2001
    Beiträge
    365
    Hallo und danke für die interessanten Beiträge.

    Mit scheint, ich bleib erst mal bei meinen RPG-Programmen
    und sammel ausreichend Know-How für die Umstellung auf SQL.

    Den konkurrierende Satzupdate habe ich durch nicht erwähnte
    Update-Zähler im Datensatz gelöst: Satz lesen und beim Chain
    vor dem update prüfen, ob der Zähler inzwischen geändert
    wurde. Klappt ausgezeichnet.

    Also Dieter, Micky würde sagen: No Satisfaction! :-))

    Gruss
    Joe

Similar Threads

  1. SQL Update aus zwei Dateien mit 3 Schlüsselfeldern
    By mk in forum NEWSboard Programmierung
    Antworten: 13
    Letzter Beitrag: 13-07-12, 08:53
  2. SQL Update 2 Dateien
    By moskito in forum NEWSboard Programmierung
    Antworten: 5
    Letzter Beitrag: 30-08-06, 17:30
  3. SQL Update über 2 i5 Systeme
    By daniel.ludwig in forum NEWSboard Programmierung
    Antworten: 5
    Letzter Beitrag: 21-07-06, 12:41
  4. Update Syntax SQL
    By wuwu in forum IBM i Hauptforum
    Antworten: 3
    Letzter Beitrag: 18-07-06, 15:31
  5. SQL .. for update of (RPG embedded SQL)
    By loeweadolf in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 01-06-06, 09:43

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •