[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Dec 2008
    Beiträge
    4

    Satzpositionierung in SQL

    Hallo Allerseits,

    per embedded SQL habe ich es geschafft, 2 Dateien mit Key-Feldern aus beiden Dateien zusammenzufügen, so dass ich die Datensätze in der richtigen Reihenfolge lesen kann. Jetzt muss ich mich nur noch auf den richtigen Satz positionieren können um dann den vorherigen und den nachfolgen Satz zu lesen. Vor und Zurück ist ja nicht das Problem, aber wie bekomme ich unter SQL so etwas wie SETLL oder SETGT hin?

    Viele Grüße

    Peter

  2. #2
    Registriert seit
    Aug 2001
    Beiträge
    2.928
    Mit Scroll Cursorn kann innerhalb eines Result Sets nur relativ positioniert werden, d.h. eine oder eine bestimmte Anzahl von Zeilen nach vorne oder zurück.

    Wenn Du so etwas wie SETLL und SETGT mit SQL machen möchtest, geht das nur durch entsprechende WHERE-Bedingungen.
    Je nach dem, was Du erreichen möchtest, musst Du zwei Cursor (zum Vorwärts- und Rückwärts-Lesen) definieren und verarbeiten.

    Birgitta
    Birgitta Hauser

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

  3. #3
    Registriert seit
    Feb 2001
    Beiträge
    20.696
    Nunja, so ganz verstehe ich die Frage nicht.
    Im Gegensatz zu F-Bestimmungen liest du mit SQL ja genau die Daten, die du benötigst.

    Wie Birgitta schon sagt, mittels WHERE-Klausel (mit Hostvariablen) bekommst du genau die geforderten Sätze was einen SETLL/SETGT/READE/REDPE überflüssig macht.

    Allerdings benötigst du hier halt immer die Sequenz:

    exec sql open MyCursor;
    dow SQLCOD = *zero;
    exec sql fetch MyCursor into ...;
    if SQLCOD = *zero;
    // Verarbeitung
    endif;
    enddo;
    exec sql close MyCursor;

    Wenn man sicher ist, dass genau 1 Satz zurückkommt, kann man auf den Cursor verzichten:

    exec sql select f1, f2, ... into :f1, :f2 from ... where ...;
    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
    Dec 2008
    Beiträge
    4
    Vielen Dank für die schnellen Antworten.

    Leider bin ich kein SQL-Experte. IBM verweist mich leider nur auf diverse Handbücher und Redbooks, in denen zwar viele Beispiele stehen, die aber nicht so ganz mein Problem darstellen.

    Es ist so, das ein Web-Programm Datensätze in diverse Dateien schreibt. Hier ist das Problem, dass die Datensätze nicht unbedingt chronologisch gemeldet werden. Die drei wichtigsten Felder sind eine Artikelnummer, ein Reparaturdatum und ein Operationscode. Für eine Artikelnummer können halt mehrere Operationscodes mit unterschiedlichem oder auch gleichem Reparaturdatum aber unterschiedlichen Operationscodes gemeldet werden:

    Satz1: Datum 23.05.07 O-Code S000
    Satz2: Datum 02.12.08 O-Code S015
    Satz3: Datum 02.12.08 O-Code S045

    Dies ist die Reihenfolge, die ich per SQL ermittel. Satz2 ist als letzter gemeldet worden und muss jetzt mit dem Inhalt anderer Felder aus der Datei mit dem vorherigen und dem nachfolgendem Satz verglichen werden. Per Parameter, weiß ich, dass es sich um den Satz2 geht, normalerweise würde ich halt ein CHAIN auf den Satz2 machen, dann einmal READE und einmal READPE.
    Ich hoffe, ich habe es verständlich ausgedrückt.

  5. #5
    Registriert seit
    Aug 2001
    Beiträge
    2.928
    Hallo,

    ich gehe davon aus, dass Du einen Cursor definiert hast, um die Datensätze in der Reihenfolge, wie Du sich möchtest zu verarbeiten.

    Weiterhin gehe ich davon aus, dass der Cursor Seriell ist, d.h. Du kannst nur vorwärts lesen.
    Mit Fetch next liest Du jeweils den nächsten Satz ein.

    Wenn Du anstatt eines seriellen einen scroll Cursor definierst, kannst Du in denen Daten vorwärts und rückwärts lesen, aber nur relativ, d.h. eine Positionierung auf einen Schlüsselbegriff ist nicht möglich.

    Mit Fetch PRIOR wird der vorhergehende Satz gelesen,
    mit Fetch NEXT wird der nächste Satz gelesen
    mit Fetch Relative x können x-1 Sätze übersprungen werden und dann der nächste Satz gelesen werden.

    PHP-Code:
    Exec SQL Declare MyCsr Scroll Cursor 
                  
    For Select ...;
    ....
    Exec SQL Fetch Next From CsrC1 into ...;
    Exec SQL Fetch Prior From MyCsSr into ...;
    Exec SQL Fetch Relative 5 from MyCsr into ...; 
    Birgitta
    Birgitta Hauser

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

  6. #6
    Registriert seit
    Feb 2001
    Beiträge
    20.696
    Solange du bei SQL kein "Order By" definierst, ist die Reihenfolge der Sätze sowieso nicht garantiert sondern von verschiedenen (scheinbar zufälligen) Bedingungen abhängig.
    Du kannst also nicht immer davon ausgehen, dass du mit jedem Select die selbe Reihenfolge erhältst.
    Ausschließlich ein "Order By" garantiert dir die gewünschte Reihenfolge der Daten.

    (Mach mal einen RGZPFM mit Angabe verschiedener LF's und prüfe das Ergebnis jedes Mal per Select.)

    An Hand deiner Beispiele kann ich nicht nachvollziehen, dass Satz2 auch tatsächlich nach Satz3 erstellt wurde.
    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
    Dec 2008
    Beiträge
    4
    Ihr seid ja wirklich schnell, vielen Dank für Eure Antworten!!

    Liebe Birgitta, ja, momentan habe ich nur einen seriellen Cursor definiert, einfach nur mal um zu sehen, ob die Datensätze auch so in der Reihenfolge erscheinen, wie ich sie brauche. Das mit dem Scroll-Cursor hatte ich schon gelesen, aber mir fehlt halt die Funktion, mich auf einen Datensatz positionieren zu können.

    Lieber Baldur, ich habe ORDER BY angegeben, es passt von der Reihenfolge der Daten alles. Nur leider fehlt halt die Positionierung (SETLL, SETGT, CHAIN). Die Erstellung des Datensatzes 2 ist nicht wichtig, sondern die Reihenfolge der Sortierung, die ich angegeben habe. Es ist halt so, dass die Händler Codes just in time melden können, oder auch Codes nachmelden können. Deshalb ist die Sortierung so. Das 1. Schlüsselfeld ist die Artikelnummer danach folgen die 2 anderen Felder. Somit sortiert sich der nachgemeldete Satz automatisch in die von mir gewünschte Reihenfolge ein. Leider muss ich bei jedem Request der vom Web-Service kommt, überprüfen, was vorher oder nachher gemeldet worden ist. Ich weiß, ist etwas verwirrend.

    Würde es Euch weiterhelfen, wenn ich die Sourcen der Dateien und meines kleinen Programmes anhänge? (Geht aber erst morgen, da ich z.Z. nicht im Büro bin)

    Nochmals DANKE

    Gruß

    Peter

  8. #8
    Registriert seit
    Mar 2002
    Beiträge
    5.365
    ich unterstelle mal, dass artikel und opcode die Sortierfelder sind:
    select *
    from mytable m
    where m.artikel = :myArtikel
    and m.opcode >= (select max(opcode)
    from mytable i
    where i.artikel = :myArtikel
    and i.opcode < :myOpcode)
    damit machst du deinen Cursor
    und mit einem Blockfetch (falls du nur lesen willst) liest du 3 Zeilen davon ein und fertig.
    Vorsicht: das vorliegende Design ist Waffenschein pflichtig!!! Wenn da gleichzeitig Einfügungen versucht werden gehts in den Ofen.

    D*B

    Zitat Zitat von PeterS Beitrag anzeigen
    Vielen Dank für die schnellen Antworten.

    Leider bin ich kein SQL-Experte. IBM verweist mich leider nur auf diverse Handbücher und Redbooks, in denen zwar viele Beispiele stehen, die aber nicht so ganz mein Problem darstellen.

    Es ist so, das ein Web-Programm Datensätze in diverse Dateien schreibt. Hier ist das Problem, dass die Datensätze nicht unbedingt chronologisch gemeldet werden. Die drei wichtigsten Felder sind eine Artikelnummer, ein Reparaturdatum und ein Operationscode. Für eine Artikelnummer können halt mehrere Operationscodes mit unterschiedlichem oder auch gleichem Reparaturdatum aber unterschiedlichen Operationscodes gemeldet werden:

    Satz1: Datum 23.05.07 O-Code S000
    Satz2: Datum 02.12.08 O-Code S015
    Satz3: Datum 02.12.08 O-Code S045

    Dies ist die Reihenfolge, die ich per SQL ermittel. Satz2 ist als letzter gemeldet worden und muss jetzt mit dem Inhalt anderer Felder aus der Datei mit dem vorherigen und dem nachfolgendem Satz verglichen werden. Per Parameter, weiß ich, dass es sich um den Satz2 geht, normalerweise würde ich halt ein CHAIN auf den Satz2 machen, dann einmal READE und einmal READPE.
    Ich hoffe, ich habe es verständlich ausgedrückt.
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  9. #9
    Registriert seit
    Dec 2008
    Beiträge
    4
    Danke für die Antwort,

    Artikel und OpCode sind Sortierfelder und ich will auch nur lesen. Das mit den 3 Sätzen war nur ein Beispiel, es können auch 50 oder mehr Sätze werden. Der zuletzt empfangene Satz ist leider nicht der letzte in der Sortierfolge, so dass ich schauen muss, wo dieser gerade empfangene Satz sich einreiht und dann dementsprechend den vorherigen und den nachfolgenden Satz lesen muss, um zu entscheiden, ob der Satz nun gültig oder nicht gültig ist. Dies entscheide ich anhand anderer Feldinhalte des vorherigen und des nachfolgenden Satzes. Ist ein bisschen verwirrend, ich weiß. Wichtig ist einfach nur, dass ich mich auf den empfangenen Satz positionieren kann. So langsam bekomme ich das Gefühl, das dies mit SQL gar nicht möglich ist und ich irgendwie eine neue Datei aus den zwei vorhandenen schaffen muss um dann via normalen RPG mit den Schlüsselfeldern aus beiden Dateien zugreifen muss.

    Peter

  10. #10
    Registriert seit
    Jan 2003
    Beiträge
    759
    Zitat Zitat von PeterS Beitrag anzeigen
    Der zuletzt empfangene Satz ist leider nicht der letzte in der Sortierfolge...
    ... rrn(filename) könnte helfen.

  11. #11
    Registriert seit
    Mar 2002
    Beiträge
    5.365
    - SQL arbeitet Mengen orientiert.
    - Rekord Löffel Ekzem ist ISAM (vor relational).
    - Was ISAM kann, kann SQL schon lange, nur die Lösung ist eine andere (in Worten: eine a n d e r e).
    - Für Ratschläge zur Lösung braucht man eine verständliche Problembeschreibung! Diese Problembeschreibung verstehe ich immer weniger, je mehr sie beschrieben wird.

    D*B


    Zitat Zitat von PeterS Beitrag anzeigen
    Danke für die Antwort,

    Artikel und OpCode sind Sortierfelder und ich will auch nur lesen. Das mit den 3 Sätzen war nur ein Beispiel, es können auch 50 oder mehr Sätze werden. Der zuletzt empfangene Satz ist leider nicht der letzte in der Sortierfolge, so dass ich schauen muss, wo dieser gerade empfangene Satz sich einreiht und dann dementsprechend den vorherigen und den nachfolgenden Satz lesen muss, um zu entscheiden, ob der Satz nun gültig oder nicht gültig ist. Dies entscheide ich anhand anderer Feldinhalte des vorherigen und des nachfolgenden Satzes. Ist ein bisschen verwirrend, ich weiß. Wichtig ist einfach nur, dass ich mich auf den empfangenen Satz positionieren kann. So langsam bekomme ich das Gefühl, das dies mit SQL gar nicht möglich ist und ich irgendwie eine neue Datei aus den zwei vorhandenen schaffen muss um dann via normalen RPG mit den Schlüsselfeldern aus beiden Dateien zugreifen muss.

    Peter
    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.696
    Wenn die Entscheidung, welcher Satz der letzte ist, von anderen Werten abhängt, so stimmt einfach die Sortierung nicht.
    Prüfe doch einfach, inwieweit du die Sortierung beeinflussen kannst.
    Hilfreich können hier CTE und Case-Ausdrücke sein:

    with xTemp as (
    select ...., case when Bedingung then Wert else Wert2 end as MySort, ...
    from ...
    )
    select * from xTemp order by MySort


    rrn(x) ist keine Lösung, da bei REUSEDLT(*YES), Standard bei SQL-Tables, rrn nicht die Eingangsfolge ist.
    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. RPGLE - SQL
    By christian_lettner in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 16-11-06, 10:15
  2. SQL - Cursor vernichten ?!?
    By FNeurieser in forum NEWSboard Programmierung
    Antworten: 3
    Letzter Beitrag: 11-10-06, 14:53
  3. SQL und OBJLCK
    By malzusrex in forum IBM i Hauptforum
    Antworten: 8
    Letzter Beitrag: 19-09-06, 11:04
  4. SQL - Fehler
    By Kaufmann in forum IBM i Hauptforum
    Antworten: 11
    Letzter Beitrag: 28-06-06, 14:11
  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
  •