Announcement

Collapse
No announcement yet.

TADODataSet::First() gibt nicht den ersten Datensatz zurück

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

  • TADODataSet::First() gibt nicht den ersten Datensatz zurück

    Hallo Leute,

    ich bin (immer noch) dabei einige Tests mit ADO durchzuführen und bin auf folgendes 'lustige Feature' gestoßen:

    adsartikel ist ein TADODataSet, dass über ODBC auf eine informix 7 DB zugreift.

    <PRE>
    if (!adsartikel->IsEmpty())
    {
    adsartikel->First();
    do
    {
    count++;
    adsartikel->Next();
    } while (!adsartikel->Eof);
    }
    </PRE>
    Laut Doku soll mit ->First() auf den ersten DS positioniert werden. Leider gibt es mir den ZWEITEN Datensatz zurück... Wenn ich die Zeile adsartikel->First(); auskommentiere funktioniert es, da wird mir dann auch der erste DS zurückgegeben. Kennt einer dieses Phänomen? Gibt es eine Abhilfe? Wie sonst kann ich sicher stellen, dass ich auf dem ersten DS stehe (außer das ADODataSet schließen und neu öffnen)?

    BCB 6 Enterprise, Update 4 installiert.

    Grüße

    Jochen

    P.S.:
    Hab's nochmal so getestet:
    <PRE>
    if (!adsartikel->IsEmpty())
    {
    if (adsartikel->Bof)
    RichEdit1->Lines->Add(adsartikelartnr->AsString + " ist der erste DS");
    adsartikel->First();
    if (adsartikel->Bof)
    RichEdit1->Lines->Add(adsartikelartnr->AsString + " ist der erste DS");
    }
    </PRE>
    Ausgabe im RichEdit:<BR>
    2 ist der erste DS<BR>
    540.047-3.0001 ist der erste DS

    Wobei "2" tatsächlich der erste DS ist...

  • #2
    Könnte das einfache eine Macke vom Informix-Treiber sein? <p>
    Schöne Grüße, Mari
    Schöne Grüße, Mario

    Comment


    • #3
      Hallo Mario,

      wenn, dann ist es eine Macke Treibers in Verbindung mit ADO, da es über die BDE einwandfrei funktioniert (unter Verwendung des gleichen ODBC-Treibers).

      Grüße Joche

      Comment


      • #4
        Hallo Jochen,<p>
        probiere mal den folgenden Code:<p>
        <pre>var rs: _Recordset;
        begin
        with TADOCommand.Create(NIL) do
        try
        Connection := ADOConnectionServer;
        CommandText := 'SELECT * From Table;';
        rs := Execute;
        rs.MoveFirst;

        if not(rs.BOF and rs.EOF) and
        (rs.Fields.Item[0].Value <> NULL)
        then ShowMessage(rs.Fields.Item[ 0].Value);
        finally
        Free;
        end;
        </pre><p>
        Dieser Code macht ähnliches mittels Delphi und kommt ohne das AdoDataset aus. Der Code arbeitet mit dem Recordset, also direkt mit Ado. Wenn da der Fehler auch ist, liegt die Macke ganz auf der Seite von Ado. Ob Dir das hilft, wird sich dann zeigen...<p>
        Schöne Grüße, Mari
        Schöne Grüße, Mario

        Comment


        • #5
          Hallo Mario,

          danke für den Source, werde ích gleich ausprobieren. <BR>
          Aber mittlerweile scheint sich doch herauszustellen, dass es sich um ein Problem des ODBC-Treibers handelt. Nach einigen Problemen ist es mir gelungen einen funktionieren OLEDB-Treiber zu installieren. Ich habe danach einfach nur die ADOConnection umgestellt und schon funktioniert es.<BR> Leider ist der OLEDB-Treiber nicht so schnell, wie der ODBC-Treiber. Die Ausführungszeit hat sich verdoppelt...

          Grüße Joche

          Comment


          • #6
            äh - kann jemand den Delphi-Source nach C++ übersetzen?!?

            also ein _Recordset erzeugen:
            <PRE>
            _Recordset* rs;
            rs = new _Recordset(NULL);
            </PRE>
            Aber das hier ist mir ziemlich unverständlich. Wo findet die Zuordnung zwischen Recordset und ADOCommand statt??
            <PRE>
            begin
            with TADOCommand.Create(NIL) do
            try
            Connection := ADOConnectionServer;
            CommandText := 'SELECT * From Table;';
            </PRE>

            Danke

            Joche

            Comment


            • #7
              Ich versuche es mal verbald zu umschreiben:<p>
              TADOCommand.Create(NIL)<br>
              <i>Erzeuge ein TAdoCommand und weise es interner Variablen AdoCommand zu.</i><p>
              Connection := ADOConnectionServer;<br>
              <i>Weise AdoCommand.Connection eine irgendwo erzeugt TAdoConnection zu</i><p>
              CommandText := 'SELECT * From Table;';<br>
              <i>Weise AdoCommand.CommandText den String zu</i><p>
              rs := Execute;<br>
              <i>Führe AdoCommand.Execute aus. Der Rückgabewert ist ein Recordset, welches in rs zwischengespeichert wird.</i><p>
              Ich hoffe, ich konnte Licht ins Dunkel bringen.<p>
              Schöne Grüße, Mario Noac
              Schöne Grüße, Mario

              Comment


              • #8
                Hallo Mario,

                ich hab's hinbekommen und es funktioniert (leider...)
                <PRE>
                int count = 0;
                unsigned short int rseof;
                _di__Recordset rs;
                TADOCommand* adocom = new TADOCommand(NULL);
                adocom->Connection = ADOConnection1;
                adocom->CommandText = "SELECT * FROM artikel WHERE (fnr = " + QuotedStr("01") + ") ORDER BY artnr ASC";
                rs = adocom->Execute();
                rs->MoveFirst();
                do
                {
                count++;
                rs->MoveNext();
                rs->Get_EOF(rseof);
                if (count > 30000)
                break;
                } while (!rseof);
                delete adocom;
                </PRE>

                Ich habe mittlerweile noch folgendes herausgefunden. Das Problem entsteht, wenn bei dem TADODataSet CursorLocation auf clUseServer gesetzt wird. Sobald dies erfolgt ist, kann der erste Datensatz nicht mehr aufgerufen werden, unabhängig davon, ob TADOConnection über den ODBC-Treiber oder den informix OLE-DB-Provider geht... Ich hasse so einen Firlefanz!

                Ich habe auch gerade noch mal geschaut. Für den BCB6 gibt es keinen spezifischen Patch für ADO. Update 4 hab' ich intalliert...

                Interessant ist noch, dass bei Deiner Version, die Ausführungszeit grundsätzlich recht schnell ist, (wie bei TADODataSet mit TCursorLocation::clUseServer). Die Ausführungsgeschwindigkeit ist unabhängig von der in der TADOConnection eingestellten CursorLocation und die Verbindung ist über den OLE-DB-Provider schneller als ODBC.

                Tja, kann ich hier unterm Strich folgern, dass es sinnvoll erscheint mit nativen ADO-Objekten zu arbeiten? Der Aufwand erscheint mir allerdings sehr hoch... (alles dynamisch zu erzeugen und zu verwalten).

                Grüße Joche

                Comment

                Working...
                X