Announcement

Collapse
No announcement yet.

Die ersten 20 Datensätze mit einer Query

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Die ersten 20 Datensätze mit einer Query

    Wie kann man mit einer TQuery die ersten 20 Datensätze z.B. einer Adressen-Tabelle erhalten?
    Danke
    Stefan

  • #2
    Hallo,

    um die Anzahl der Datensätze zu begrenzen, stehen je nach der eingesetzten Datenbank verschiedene Techniken zur Verfügung.

    <b>BDE-Eigenschaft MAX ROWS</b>:

    Über die BDE-Verwaltung kann die Treiber-Eigenschaft <b>MAX ROWS</b> für einen Alias fest zugewiesen werden - die BDE liefert damit nur noch die hier vermerkte Anzahl von Datensätzen in einer Abfrage zurück. Der Vorgabewert von -1 schaltet diese Begrenzung ab.

    Immer dann, wenn damit zu rechnen ist, daß nur eine bestimmte SQL-Abfrage via TQuery sehr große Datenmengen ergeben kann, kann eine Begrenzung der maximal zurückgelieferten Datensätze nur für diese eine Abfrage sinnvoll sein. Über einen geringfügig modifzierten TQuery-Nachfolger kann das Programm zur Laufzeit die Anzahl der maximal zum Client übertragenen Datensätze begrenzen. Somit legt der Wert in FMaxRowCount fest, wieviele Datensätze in der Datenmenge von TQuery maximal erscheinen.

    <pre>
    Check(DbiValidateProp(hDBIObj(Query1.Handle), curMAXROWS, True));
    Check(DbiSetProp(hDBIObj(Query1.Handle), curMAXROWS, FMaxRowCount));
    </pre>

    Da die Begrenzung durch die BDE realisiert wird, kann dies für alle BDE-fähigen Datenbanken eingesetzt werden.

    <b>Stored Procedure für den InterBase</b>:

    Eleganter als die BDE-Begrenzung ist eine <b>Stored Procedure</b> in der InterBase-Datenbank, die als Select Procedure nur die als Parameter übergebene Anzahl von Datensätzen zurückliefert:
    <pre>
    CREATE PROCEDURE GetFirstXKunden (rows INTEGER)
    RETURNS (kundenid INTEGER, vorname CHAR(35), nachname CHAR(35)) AS
    BEGIN
    IF (rows <1) THEN EXIT;
    FOR SELECT kundenid, vorname, nachname
    FROM kundenimp
    INTO :kundenid, :vorname, :nachname
    DO
    BEGIN
    SUSPEND;
    rows = rows -1;
    IF (rows <1) THEN EXIT;
    END
    END
    ^
    </pre&gt

    Comment


    • #3
      Hallo Andreas,

      ich arbeite mit einer Paradox-Datenbank. Ich brauche nur für eine Query eine Begrenzung. Wie muss ich denn den Nachfolger der TQuery modifizieren, dass es geht

      Comment


      • #4
        Hallo Stefan,

        das könnte zum Beispiel so aussehen:
        <pre>

        unit MaxRowQuery;

        interface

        uses
        Windows, Messages, SysUtils, Classes, DB, DBTables;

        type
        TRestrictedQuery = class(TQuery)
        private
        FMaxRowCount: Longint;
        protected
        procedure PrepareCursor; override;
        published
        property MaxRowCount: Longint read FMaxRowCount write FMaxRowCount;
        end;

        implementation

        uses BDE;

        procedure TRestrictedQuery.PrepareCursor;
        begin
        inherited PrepareCursor;
        if FMaxRowCount > 0 then
        begin
        Check(DbiValidateProp(hDBIObj(Handle), curMAXROWS, True));
        Check(DbiSetProp(hDBIObj(Handle), curMAXROWS, FMaxRowCount));
        end;
        end;

        end.
        </pre>

        Im Programm wird das Ganze dann wie folgt eingesetzt:
        <pre>
        resourcestring
        cSQL = 'SELECT CUST_NO, CUSTOMER, CONTACT_FIRST FROM CUSTOMER';

        { Die Instanz FQuery2 soll nur maximal 4 Datensätze aus dem
        Resultset vom Server laden und anzeigen (MaxRowCount).
        Im Gegensatz zu stellt Query1 alle Daten aus der Ergebnismenge
        des Servers dar. }

        procedure TFormMain.FormCreate(Sender: TObject);
        begin
        FQuery2 := TRestrictedQuery.Create(self);
        with FQuery2 do
        begin
        SQL.Add(cSQL);
        DatabaseName := 'IB_Test';
        MaxRowCount := 4;
        end;
        DataSource2.DataSet := FQuery2;
        end;
        </pre&gt

        Comment


        • #5
          Hallo Andreas,

          danke für das Beispiel. Allerdings bekomme ich bei der Anweisung:

          Check(DbiValidateProp(hDBIObj(Handle), curMAXROWS, True));
          die Fehlermeldung:'Merkmal nicht verfügbar'.

          Ich kann in der BDE-Verwaltung für Paradox auch keine Zeile mit MAXROWS finden. Diese Zeile ist nur bei den SQL-Servern vorhanden.

          Ich habe mal in der Delphi-Hilfe nachgeschaut. MaxRows lässt sich tatsächlich nur für SQL-Datenbanken ändern, wie folgender Text aus der Delphi-Hilfe belegt:

          // Make sure the table type is not dBASE or Paradox (must be SQL based)
          if (DBType = 'STANDARD') then
          raise EDBEngineError.Create(DBIERR_NOTSUPPORTED);
          // Make sure that the property can be set

          rslt := DbiValidateProp(hDBIObj(Table.Handle), curMAXROWS, True);

          Leider funktioniert diese Lösung nicht. Fällt Dir noch was anderes ein?

          Gruß
          Stefa

          Comment


          • #6
            Hallo,

            ich sollte vielleicht doch wieder einmal mit Paradox hantieren ;-

            Comment


            • #7
              Dieses Problem kann man auch elegant mit der Komponente TClientDataSet
              lösen.

              Das Rezept bei Delphi 3:
              Man benötigt die Komponenten TQuery + TClientDataSet + TDataSource.

              Initalisierung

              TClientDataSet.Provider:=TQuery.Provieder;
              TDataSource.DataSet:=TClientDataSet.
              TClientDataSet.PacketRecord:=20;
              TQuery.SQL.Add('SELECT * FROM ADRESSE');
              TClientDataSet.Open;
              .....
              ....

              Comment


              • #8
                Hallo

                Die ersten 20 Datensätze müsste man auch einfach über das SQL-Statement
                'Select Top 20 * from Adresse'
                erhalten.

                Dieser Parameter ist (,glaub ich) Standard-SQL.

                Tschau,
                Ka

                Comment


                • #9
                  Hallo,

                  ein <b>SELECT TOP</b> ist <b>kein</b> SQL-Standard ;-)

                  Es gibt für dieses Problem mehrere Alternativen, einige wurden bereits hier im FORUM vorgestellt. Eine Suche nach <b>MaxRows</b> sollte weiterhelfen

                  Comment

                  Working...
                  X