[NEWSboard IBMi Forum]
Seite 2 von 2 Erste 1 2
  1. #13
    Registriert seit
    Jan 2001
    Beiträge
    851
    Danke für die Info's

    Gruß
    Michael

  2. #14
    KM is offline [professional_User]
    Registriert seit
    Apr 2003
    Beiträge
    1.014
    Hallo,

    also wenn Du wirklich eine komfortable Suche erstellen willst, solltest Du ein wenig Java einsetzen und Lucene verwenden. Aber das ist ein anderes Thema.

    Wir haben Dein Problem in etwa so realisiert. Die Kommunikation zwischen Client und AS/400 erfolgt über Keyed Dataqueue und Resultset. Bei der Suchanfrage des Client wird die Session-ID, der Suchstring und diverse Parameter (z.B. die gewählte Seitennummer) an die Input-Dataqueue übergeben, die ein Asynchronjob überwacht. Wenn die Seitennummer = 0, dann heißt das für uns es wird eine neue Suche durchgeführt, ansonsten wird nur in der Ergebnisliste navigiert. Je nach Seitennummer wird der entsprechende Teil der Ergebnisliste zusammen mit der Session-ID in eine Output Dataqueue zurück geschrieben (sozusagen als Zwischenspeicher). Der Inhalt bleibt in der Output-Dataqueue so lange erhalten, bis eine neue Suche ausgeführt wird. Beim Blättern bzw. Navigieren auf eine bestimmte Ergebnisseite lesen wir nur den betreffenden Teil aus dem Ergebnisfeld der Output-Dataqueue ein und geben das dem Client als Resultset zurück.

    Gruß,
    KM

  3. #15
    Registriert seit
    Jun 2010
    Beiträge
    24
    Ich habe hier ein Beispiel, vielleicht hilft das ja weiter:

    Code:
        /**
        * Build LIMIT query
        */
        function _sql_query_limit($query, $total, $offset = 1, $max_records = 0, $cache_ttl = 0)
        {
            $this->query_result = false;
    
            // if $total is set to 0 we do not want to limit the number of rows
            if ($total == 0)
            {
                // Having a value of -1 was always a bug
                $total = '18446744073709551615';
            }
            if ($max_records == 0)
            {
                // Having a value of -1 was always a bug
                $max_records = '18446744073709551615';
            }
    
            $end_offset = $offset + $total - 1;
    
            if ( $end_offset > $max_records )
            {
                $diff = $end_offset - $max_records;
                $end_offset = $end_offset - $diff;
                $total = $total - $diff;
            }
    
    
            // DB2 UDB for iSeries (V5R4)
            $search_string = 'ORDER BY';
            $sort_order = 'ASC';
            $sort_order_desc = 'DESC';
            $reverse_order = '';
            $order_query = '';
            $h_query = strtoupper($query);
            if ( stripos($h_query, $search_string) !== false )
            {
                $pos = stripos($h_query, $search_string);
                $order_query = stristr($h_query, $search_string);
                $order_found = false;
                if ( stripos($order_query, $sort_order) !== false )
                {
                    $reverse_order = 'DESC';
                    $order_found = true;
                }
                if ( stripos($order_query, $sort_order_desc) !== false and !$order_found )
                {
                    $reverse_order = 'ASC';
                    $order_found = true;
                }
                if ( !$order_found )
                {
                    $reverse_order = 'DESC';
                }
            }
            else
            {
                    $reverse_order = 'DESC';
            }
    
            $query = 'With UR as (' . $query . ' FETCH First ' . $end_offset . ' Rows Only),
                           SR as (SELECT * FROM UR ' . $order_query . ' ' . $reverse_order . ' FETCH First ' . $total . ' Rows Only)
                      SELECT * FROM SR ' . $order_query;
    
            return $this->sql_query($query, $cache_ttl);
        }
    Man muss vorher nur ermitteln wie viele Datensätze insgesamt in der Abfrage zurück geliefert werden. Ein Schwachpunkt hat die Abfrage noch (bin leider noch nicht dazu gekommen das zu fixen), nämlich es darf beim ORDER BY nur ein Feld angegeben werden.

    EDIT: Bei Join Abfragen muss man die Felder eindeutig mit dem AS-Clause im Select definieren (t.PRICE as PRICE).
    Last edited by bussibaer; 30-09-10 at 12:48. Grund: Join Einschränkung nachgeschoben
    Schönen Gruß aus Kiel

    Jörg

  4. #16
    Registriert seit
    Jan 2001
    Beiträge
    851
    Hallo zusammen,

    vielen Dank. Demnächst wird das Thema
    wahrscheinlich akut.
    Dann werden wir sehen.

    Jörg:
    Arbeitet ihr eigentlich mit connect oder mit p_connect ?


    Gruß
    Michael

  5. #17
    Registriert seit
    Jun 2010
    Beiträge
    24
    Mit pconnect und autocommit, das andere ist leider zu langsam.
    Schönen Gruß aus Kiel

    Jörg

  6. #18
    Registriert seit
    Oct 2004
    Beiträge
    251

    Post

    So jetzt muss ich auch noch meinem Senf dazugeben:

    1. Hier der Syntax für Paging auf der AS/400:

    Code:
    SELECT * FROM                                 
     ( SELECT kunde.*, rownumber() over( ORDER BY  
        firnr, kunr ) as rownum               
     FROM mkun WHERE firnr = 1 and         name like '%MAIER%' )                
     as inner where rownum between 50 and 100
    Ich habe zwar noch keine Probleme ohne gehabt, aber es wird empfohlen in der ORDER BY einen eindeutigen Schlüssel zu haben - also zumindest an die Wunschsortierung dranhängen.

    Bei großen Dateien habe ich bessere Erfahrungen gemacht, wenn auch der inner Join gleich sortiert ist:

    Code:
    SELECT * FROM                                          
     ( SELECT kunde.*, rownumber() over( ORDER BY           
        firnr, kunr ) as rownum                        
     FROM kunde WHERE firnr = 1 and                        
        name like '%MAIER%' order by firnr, kunr) 
     as inner where rownum between 50 and 100
    Bei diesem Select werden die Zeilen 50-100 ausgegeben.

    2. PHP: iieeehhh...

    3a) Denn SQL-Syntax habe den Hibernatesourcen entnommen. Wenn man mit Hibernate arbeitet braucht man davon nichts zu wissen..

    3b. Bei größeren Anwendungen zahlt sich Hibernate (Java) bzw. NHibernate (für Dot.Net) aus. Für die optimale Performance muss man sich dann aber schon richtig damit beschäftigen.

    Bei meinem letzten Project habe auch noch das Feature Hibernate Search verwendet:

    Neben der Datenbankanbindung kann man mit wenigen (fett) Schlüsselwörtern auch die Indexierung für die Volltextsuche mitmachen lassen - im Hintergrund werkelt Lucene. Auf diese Weise ist es ein leichtes den Anwender schnell mal
    nach: Name/Ort/Postleitzahl suchen zu lassen, z.B. MAIER WIEN.

    Einfacher ist das Leben sicher mit Id's statt Multikeyfeldern, Hibernate bietet aber immer eine Möglichkeit an, Multikeyfelder abzubilden.

    Noch noch was zu Java: So manchem Umsteiger mögen die "vielen" Schichten in Java speziell bei der Trennung von Model, Controll und View als Overhead hoch 5 vorkommen.

    Aber gerade durch die eigene Modelschicht die z.B. eine Funktion für die Kundensuche hat, ist es leicht eine langsame (oder schlechte wg. z.B. Umlaut ae <> ä) Datenbanksuche durch eine Volltextsuche zu ersetzen.


    Hier noch eine Beispielklasse (~ Record der Datei KUNDE)
    @Entity
    @Table(name = "KUNDE")
    @Indexed
    @Analyzer(impl = GermanUmlautAnalyzer.class)


    public class Kunde implements Serializable {


    @Id
    @DocumentId(name="firkund")
    @FieldBridge(impl = com.at.od.notlauf.model.domains.KundenPKBridge.cla ss)

    @EmbeddedId
    KundePK kundePK; // Darstellung Mehrfachschlüssel
    @ManyToOne
    @JoinColumn(name="FIRMA", referencedColumnName = "FIRMA",insertable=false,updatable=false)
    Firma firma;

    @Column(name = "NAME")
    @Field(index=Index.TOKENIZED, store=Store.NO)
    @Boost(2f)

    String name;

    @Column(name = "ZUSATZ")
    String zusatz;
    @Column(name = "STRASSE")
    String strasse;
    @Column(name = "ORT")
    @Field(index=Index.TOKENIZED, store=Store.NO)
    String ort;

    @Column(name = "PLZ")
    @Field(index=Index.UN_TOKENIZED, store=Store.NO)
    String plz;

    @Column(name = "LAND")
    String land;
    @Column(name = "KURZBEZ")
    @Field(index=Index.TOKENIZED, store=Store.NO)
    String kurzBezeichnung;
    @Column(name = "BONICD")
    int boniCode;

Similar Threads

  1. Antworten: 6
    Letzter Beitrag: 26-07-06, 12:22
  2. IFS Datei Daten hinzufügen
    By sim in forum NEWSboard Programmierung
    Antworten: 11
    Letzter Beitrag: 18-05-06, 08:00
  3. Antworten: 1
    Letzter Beitrag: 24-04-06, 10:37
  4. dspjrn mit minimierten aufgezeichneten Daten
    By rebe in forum NEWSboard Programmierung
    Antworten: 0
    Letzter Beitrag: 28-04-05, 15:49
  5. Daten Import Tool + Dublettensuche für i5 CRM
    By Heinz Molter in forum Archiv NEWSblibs
    Antworten: 0
    Letzter Beitrag: 31-08-04, 09:48

Berechtigungen

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