[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Jan 2012
    Beiträge
    1.120

    Datei ohne eindeutigen Schlüssel mit SQL Cursor abarbeiten und updaten

    Hallo,
    vielleicht weiß jemand, ob folgendes geht:

    Ich habe eine Datei, die keinen eindeutigen Schlüssel hat und möchte diese Datei durchlesen und jeden Satz, den ich verarbeitet habe, updaten. Mit Record Level Access ist das ja kein Problem: Satz mit read lesen und sperren, Feldinhalt ändern und dann mit update speichern und die Sperre aufheben.

    Geht das auch mit embedded SQL?
    Kann ich einen cursor "for update" deklarieren? Falls ja: Wird der aktuelle Datensatz des Cursors, der mit fetch abgerufen wird, dann gesperrt?

    Dieter

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Mittels "for Update" wird beim fetch der Satz gesperrt.
    Den update führt man dann mittels

    update myfile set ...
    where current of CursorName

    durch.
    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
    Registriert seit
    Dec 2004
    Beiträge
    203
    Hallo.
    Vor demselben "Problem" stehen wir / ich derzeit in c# ... weiss jemand für diese Sprache evtl. auch
    eine Methode / Funktion ...
    Gruß,
    Ralf

  4. #4
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Vielen Dank Baldur. Das ist genau die Antwort, die ich brauchte.

    Dieter

  5. #5
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Doch noch eine Nachfrage: Ich habe eben in einem älteren Beitrag gelesen, dass man bei einem "For Update" Cursor keinen sort angeben kann. Habe ich das richtig verstanden und falls ja, ist das immer noch so?

    Dieter

  6. #6
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Nun, bei ODBC/JDBC/OLEDB kommt man an den CursorNamen des Treibers meist nicht dran.
    Beim "current of CursorName" muss dieser ja explizit angegeben werden.

    Hier hilft nur tatsächlich ein UniqueKey für die Zieltabelle.
    Ab V7R1 gibt es einen internen Index für die RRN().

    Also
    select rrn(myfile) as rrnnr, blabla ...

    update myfile ... where rrn(myfile) = rrnnr

    Vor V7 kann das schon mal eine etwas längere Aktion werden.
    Eine Satzsperre erfolgt natürlich erst beim Update, nie beim Lesen.
    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

  7. #7
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    ... das ist (zumindest) für JDBC nicht korrekt. ResultSet hat updateXXX Methoden für Feldinhalte neu zu setzen und updateRow() nagelt das dann in den aktuellen Satz.

    Das mit den Sperren ist komplett falsch: das ist alles per Commit Level einstellbar und ohne Commit ist bei einem updatable Cursor der aktuelle Satz, ähnlich wie bei Rekord Löffel Ekzem gesperrt.

    D*B

    BTW: positioned update bringt massiv Performance Vorteile.

    Zitat Zitat von Fuerchau Beitrag anzeigen
    Nun, bei ODBC/JDBC/OLEDB kommt man an den CursorNamen des Treibers meist nicht dran.
    Beim "current of CursorName" muss dieser ja explizit angegeben werden.

    Hier hilft nur tatsächlich ein UniqueKey für die Zieltabelle.
    Ab V7R1 gibt es einen internen Index für die RRN().

    Also
    select rrn(myfile) as rrnnr, blabla ...

    update myfile ... where rrn(myfile) = rrnnr

    Vor V7 kann das schon mal eine etwas längere Aktion werden.
    Eine Satzsperre erfolgt natürlich erst beim Update, nie beim Lesen.
    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
    Aug 2001
    Beiträge
    2.873
    Doch noch eine Nachfrage: Ich habe eben in einem älteren Beitrag gelesen, dass man bei einem "For Update" Cursor keinen sort angeben kann. Habe ich das richtig verstanden und falls ja, ist das immer noch so?
    Ich kenne jetzt den Eintrag nicht, aber eigentlich ist es umgekehrt.
    Ein Cursor ist normalerweise updatebar, wenn nur Spalten aus einer einzigen Datei angegeben wurden.
    In einem solchen Fall ist die Angabe FOR UPDATE nicht erforderlich, auch wenn der Cursor (bzw. die Datensätze) mit WHERE CURRENT OF upgedated wird.
    Sobald jedoch ORDER BY angegeben wurde ist der Cursor nicht mehr updatebar (READ ONLY), es sei den es würde FOR UPDATE OF hinzugefügt.

    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

  9. #9
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    OK, das ist dann ja noch besser. Dann kann ich sortierte Cursor ja auch updaten!

    Vielen Dank.
    Dieter

  10. #10
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    UpdateRow() bei Java ist gefährlich!
    Java generiert einen SQL-Update:

    update mytable set field=newvalue where field1=f1oldvalue and field2=f2oldvalue ...

    Wenn in dem Resultset nicht alle Felder aufgeführt sind, die den Satz eindeutig identifizieren kann und wird es zu multiplen Updates kommen.

    Ohne eine Deklaration "for update" wird beim Lesen keine Sperre gesetzt, da dies ja nicht erforderlich ist.
    Mit "for update" bzw. enstsprechendem CommitLevel wird beim Lesen bereits gesperrt.

    Arbeitet man (wie auf der AS/400 leider häufiger) ohne Commit und Journal, wird bei "for Update " die 1. Sperre gesetzt und beim "Update ... where " über einen 2. ODP die 2. Sperre angefordert, was ja nicht geht.

    Nur beim "update ... current of CursorName" wird die Sperre des Selects verwendet.

    Auch bei Java (und das gilt für alle ODBC/JDBC/OLEDB) kann ich den internen CursorNamen nicht erfragen, da der meist vom Treiber bzw. automatisch erst auf dem Server generiert wird.

    Für Remote-SQL ist daher eigentlich Journalisierung, Transaktionssteuerung sowie ein Unique Key Vorschrift.
    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

  11. #11
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    @Baldur: Heute ist nicht Dein Tag!

    Ein updateRow() ändert höchstens eine Zeile des ResultSets, egal was ich da für Felder ausgewählt habe und das macht der auch nur, wenn das ResultSet nicht CONCUR_READ_ONLY oder geschlossen ist, oder gerade vorher insertRow() gemacht wurde.

    Satzsperren werden bei SQL normalerweise auf Ebene der Connection gehalten, bei korrektem vorgehen kann man sehr wohl mit Sperre lesen und dann einen searched update machen, geht das nicht, hat der Treiber einen Schuss.

    D*B

    PS: Ich kanns nicht oft genug sagen: arbeitet man mit SQL ohne Commit und macht Änderungen an Tabellen, dann macht man was verkehrt, egal mit welcher Datenbank auch immer!!!
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  12. #12
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    @Dieter
    Bei Java macht dir wohl keiner was vor.
    Also ich muss dir recht geben.
    Bei "CONCUR_UPDATABLE" generiert Java (bzw. der Treiber der AS/400):
    UPDATE TestUpd SET "F2"=? WHERE CURRENT OF "CRSR0001"
    Damit kann wenigstens Java mehr als alle anderen.

    In ADODB (COM-Schnittstelle) funktioniert dies leider nicht, da tatsächlich ein SQL der Art
    update MyFile set FX=NewVal where fx=fxOldval and fy=fyoldval ...

    Dies liegt in der Tatsache begründet, dass ein ADODB.Recordset "offline" bearbeitet werden kann.
    Und nur als "ClientCursor" besteht überhaupt nur ein Updatable Recordset.

    In ADO.NET ist es noch ganz anders, da ADO.NET grundsätzlich als Offline-Version konzipiert ist:
    Ein Reader kann nur lesen und diesen benötigt man zum Füllen einer DataTable bzw. eines DataSet's.
    Per DataAdapter kann man sich dann die Insert/Update/Delete's genrieren lassen, die allerdings immer von den selektierten Feldern abhängen.
    Einen "update ... current of ..." gibt es definitiv nicht, da nun mal ein Reader grundsätzlich nur vorwärts lesen kann, Methode Read.

    Um also tatsächlich den richtigen Satz zu ändern kommt man um einen Unique-Key nicht herum.
    Selbst Entity-Frameworks benötigen einen solchen Schlüssel, wobei die wenigsten mit einem "Compound-Key", also mehrere Schlüssel, zurecht kommen. Diese benötigen fast alle eine Identity-Spalte.
    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

Similar Threads

  1. FTP erstellt Datei auf fernem System - aber ohne Datenbankfelder
    By msost in forum NEWSboard Programmierung
    Antworten: 5
    Letzter Beitrag: 21-01-14, 11:31
  2. Artikel: SQL: dynamisches Select ohne Cursor
    By NEWSolutions Redaktion in forum NEWSolutions artikel
    Antworten: 0
    Letzter Beitrag: 05-12-13, 18:03
  3. doppelter Schlüssel
    By SBaum in forum IBM i Hauptforum
    Antworten: 1
    Letzter Beitrag: 24-01-03, 11:17
  4. Antworten: 4
    Letzter Beitrag: 31-10-02, 07:56
  5. Berechtigung zum Updaten einer Tabelle
    By Sascha Storzum in forum IBM i Hauptforum
    Antworten: 10
    Letzter Beitrag: 22-08-02, 07:37

Berechtigungen

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