SQL: Ergebnisse richtig zählen?



  • Hallo,

    ich mach jetzt schon ein paar Tage dran rum, und mittlerweile funktioniert sogar schon ein bisschen was. Ich möchte aus einer Datenbank via SELECT etwas auslesen, und dann anhand der Ergebnisse weiterverarbeiten. Datenbank ist eine mySQL...

    Soweit okay. Ich führe den Query aus, ich bekomme auch Ergebnisse, jedoch stimmt die Anzahl der Ergebnisse nicht. Ich sollte 5 Rows zurückbekommen, mein Counter gibt mir aber 6 zurück! Mit der Funktion RecordsCount erhalte ich jedes Mal "-1", also total falsch. Wie ermittele ich nun am einfachsten die Anzahl der zurückgegebenen Datensätze? Ich habe bisher Datenbanktechnisch nur mit PHP gearbeitet, da kann ich das ja ganz easy via mysql_num_rows(); machen.

    Hier mein Code (lasst euch nicht irritieren, das soll alles mittels eines Timers ausgeführt werden, habe das aber zum Testen momentan mit nem Button):

    void __fastcall TfrmMain::Button2Click(TObject *Sender)
    {
    /* °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
       °°°°       ZdD Core Schedulder      °°°°
       °°°      .: 5 Minutes Timer : .      °°°
       °°                                    °°
       °      Rev 1.0 (11.07.2008) Alpha      °
       °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°  */
    
    // Datenbank abfragen
    // ...................................................................
    qCoreMail->SQL->Clear();
    qCoreMail->SQL->Add(AnsiString("SELECT cmail_id,cmail_to,cmail_account,cmail_chara,cmail_type,cmail_text,cmail_attach,cmail_sent,cmail_sentdate from core_mail where cmail_sent !='1'"));
    qCoreMail->Open();
    qCoreMail->First();
    
    int iQueryMailResults,iQueryMailRecords;
    iQueryMailResults = 0;
    
    while(!qCoreMail->Eof)
            {
            iQueryMailResults++;
            //LOG->Lines->Add("Result Nr. "+IntToStr(iQueryMailResults));
            qCoreMail->Next();
    
            }
    
    // Casting
    LOG->Lines->Add("Fetched: "+IntToStr(iQueryMailResults));
    }
    //---------------------------------------------------------------------------
    

    Ist bestimmt ganz easy, Danke für die Mühen!

    Gruß,
    Sebastian



  • Hallo

    Dafür gibt es doch die Eigenschaft RecordCount. Eventuell must du aber vorher das DataSet zwingen alle zu zählen :

    qCoreMail->Open();
    
    // erzwingt eine korrekte Zählung aller und nicht nur der
    // gecached Datensätze
    qCodeMail->Last(); 
    qCoreMail->First();
    
    LOG->Lines->Add("Fetched: "+IntToStr(qCoreMail->RecordCount));
    

    bis bald
    akari



  • Und falls MySQL (entweder MySQL selbst, oder MySQL in Verbindung mit der gewählten Zugriffskomponente) RecordCount tatsächlich nicht unterstützt, kannst Du immer noch einen SELECT COUNT(*) WHERE (...) machen.



  • Hallo akari,

    vielen Dank für Deine Hilfe und Deinen Denkanstoß. Ich habe den Code gemäß Deinen Angaben erweitert:

    // Datenbank abfragen
    // ...................................................................
    qCoreMail->SQL->Clear();
    qCoreMail->SQL->Add(AnsiString("SELECT cmail_id,cmail_to,cmail_account,cmail_chara,cmail_type,cmail_text,cmail_attach,cmail_sent,cmail_sentdate from core_mail where cmail_sent !='1'"));
    qCoreMail->Open();
    qCoreMail->Last();
    qCoreMail->First();
    
    int iQueryMailResults,iQueryMailRecords;
    iQueryMailResults = 0;
    iQueryMailRecords = qCoreMail->RecordCount;
    
    while(!qCoreMail->Eof)
            {
            iQueryMailResults++;
            //LOG->Lines->Add("Result Nr. "+IntToStr(iQueryMailResults));
            qCoreMail->Next();
    
            }
    
    // Casting
    LOG->Lines->Add("Fetched: "+IntToStr(iQueryMailResults));
    LOG->Lines->Add("Records: "+IntToStr(iQueryMailRecords));
    
    // ...................................................................
    

    Ich bekomme als Ergebnis (Records) auch die 6 zurückgeliefert. Das ist schon Mal viel viel besser als -1 🙂
    Ich habe via PMA eben den Query Mal auf die Datenbank losgelassen und konnte verifizieren, dass das Ergebnis (also 6 Datensätze) korrekt ist.

    Mein "Problem" ist damit gelöst. Ich hätte jedoch noch eine Verständnisfrage:
    Muss ich zum Zählen der Ergebnisse jedes Mal

    qCoreMail->Open();
    qCoreMail->Last();
    qCoreMail->First();
    

    ausführen? Vorher natürlich noch ein Clear(), is klar, aber wenn ich das richtig sehe, dann sauge ich mir alle Ergebnisse des Queries in meinen RAM und zähle dann, oder ist das ein serverseitiges Zählen? Ich habe bedingt auf den Feldern, die zurückgegeben werden, vor, Queries zu verschachteln. Da müsste ich mir am End ja noch eine Funktion schreiben, oder? Sonst blicke ich am Ende wohl überhaupt nicht mehr durch bzw. hole mir zu viele Fehlerquellen ins Boot, oder?

    Ist für mein Programm momentan nicht wirklich kritisch, da 6 Datensätze schon viele Ergebnisse wären, aber für zukünftiges wäre das gut zu wissen, denn da hantiere ich mit größeren Ergebnismengen.

    Danke und Gruß,
    Sebastian



  • Hallo

    Der von mir gezeigte Trick ist in der Tat Clientseitig, d.h. im schlimmsten Fall müßen unnötigerweise alle Datensätze in den Speicher geladen werden.

    Wenn du darin ein Performance-Problem siehst (das sich sicher erst ab ein paar Hundert Datensätzen auswirkt) dann must du das Joe angesprochene SELECT COUNT ausführen. Das ist rein Serverseitig und übermittelt letztendlich nur die reine Anzahl, nicht die Datensätze selber.

    /Edit : Mit den cpp-Tags anstelle der Code-Tags bekommst du hier im Forum auch schönes Syntaxhighlightning.

    bis bald
    akari



  • Vielen Dank Euch beiden! Zukünftig verwende ich cpp 😉

    Gruß,
    Sebastian


Anmelden zum Antworten