Datenbank Frage SQL [gelöst]



  • Ich arbeite gerade an einem kleinen Projekt.

    Kann mir evtl. jemand einen Tipp geben wie ich aus der SQL Query die ausgeführt wurde rausbekomme - welche ID der Datensatz hat -.

    Die Tabelle hat das folgende Schema (Spalten):

    ID (Long Integert) Primary AUTOID
    NAME (TEXT) 
    BESCHREIBUNG (TEXT)
    

    Beispielcode:

    // Kategorie
            SQLKategorie->ConnectionString = Connection;
            SQLKategorie->SQL->Add("SELECT NAME FROM KategorieAusgaben ORDER BY ID");
            SQLKategorie->Open();   // Active = true;
            while (!SQLKategorie->Eof){
            ComboBox2->Items->Add(SQLKategorie->FieldValues["NAME"]);
            ComboBox2->Items->
            SQLKategorie->Next();
            } SQLKategorie->Active = false;
    

    Ich meine eine SQL Abfrage wird ja in Zeile 2 durchgelaufen. Als Rückgabe gibts ja dann die Werte z.B. mit FieldValues["ID"] kann ich ja die ID des aktuellen durchlaufsprüfen. Kann ich diese ID dem Listenfeld COMBOBOX2 irgendwie vergeben? Damit ich diesen dann abfragen kann oder muss ich jedesmal eine SQL Query durchführen nach dem Prinzip: "SELECT ID FROM KONTO WHERE KONTONAME=:KONTONAME LIMIT 1".

    Lieben Gruß und danke für die Antworten.



  • das sql müsste lauten:

    SELECT NAME, ID FROM KategorieAusgaben ORDER BY ID
    

    dann solltest du mit 'FieldValues["ID"]' die id kriegen.
    bei comboboxen kann man pro zeile noch einen 'unsichtbaren' wert eintragen. den könntest du beispielsweise mit der id belegen.
    wie das mit deiner 'Combobox' klasse geht, müsste in der doku stehen...
    🙂



  • Hallo

    Hier wird das Prinzip mit dem unsichtbaren Wert erklärt was vista meint.

    Wenn du bereits mit anderen Komponenten aus der DBE arbeitest solltest du dir TDBComboBox/TDBLookupComboBox anschauen, die sind genau für dieses Problem da.

    bis bald
    akari



  • Habs noch nicht getestet, aber vielen Dank schonmal. Setzte mich nun dran.

    Naja irgendwie muss ich ja dann mit Zeigern arbeiten und das wollte ich erlichgesagt nicht. Gibt's denn keine Lösung wie man einem Eintrag in der Combobox einen Hiddenwert übergibt? Kann ich den den Stringbereich prüfen?

    Nehmen wir mal an ich füge nun bei jedem Eintrag hinter dem Namen einfach (17) mit ein. Gibts hierfür eine Methode um diese Zahl also 17 oder so also alles was in der Klammer steht in eine Variable speicher? Ich kenn mit da nur mit PHP aus wie man per Muster und String arbeitet. Aber im BCB leider noch nicht. Würd mich aufjedenfall freuen, wenn ihr mir helfen könntet.
    Das müßte doch wie folgt gehen oder irre ich mich da?

    // Kontopulldown
            SQLKonto->ConnectionString = Connection;
            SQLKonto->SQL->Add("SELECT ID,KONTONAME FROM KONTEN ORDER BY KONTONAME");
            SQLKonto->Open();       // Active = true;
            while (!SQLKonto->Eof) {
            ComboBox1->Items->Add((SQLKonto->FieldValues["KONTONAME"]) + (" ("+SQLKonto->FieldValues["ID"]+")"));
            SQLKonto->Next();
            } SQLKonto->Active = false;
    
    // ID in Variable
    AnsiString IDvariable;
    IDvariable = ComboBox->SubString(int index, int count);
    

    Liebe Grüße und big thanks 🙂



  • Hallo

    Gibt's denn keine Lösung wie man einem Eintrag in der Combobox einen Hiddenwert übergibt?

    Die Lösung wird doch in dem Link erklärt.

    Naja irgendwie muss ich ja dann mit Zeigern arbeiten und das wollte ich erlichgesagt nicht.

    Must du aber. Ist aber auch nicht schlimm, Zeiger sind nichts schlechtes. Bei dir stellt sich die Frage ob du zusätzlich zu den Zeigern noch dynamische Speicherreservierung brauchst. Aus der gezeigten Tabellenstruktur geht hervor das deine ID ein "Long Integer" ist. Ich weiß nicht genau mit welchen DB-System du arbeitest, in den meisten Fällen sollte so ein Wert in den C++ Datentyp unsigned int passen. Das bedeutet du zwingst die ComboBox einfach den ID-Wert direkt als Objekt zu übernehmen.

    unsigned int ID = ...; // ID aus Datensatz letzten
    AnsiString Name = ...; // Name aus Datensatz lesen
    ComboBox->Items->Add(Name, reinterpret_cast<TObject*>(ID)); // Name mit ID in ComboBox eintragen
    

    Nun wird Name immer in Zusammenhang mit der ID verwaltet, auch wenn in der ComboBox sortiert oder gelöcht wird.
    Das ganze kannst du nun auch einfach wieder auslesen

    unsigned int ID = reinterpret_cast<unsigned int>(ComboBox->Items->Object[0]);
    

    Das ganze ist zwar nicht schön aber übersichtlich.
    Wenn dein ID-Wert nicht in ein unsigned int passt oder du generell komplexe Datentypen verküpfen willst solltest du von TObject eine neue Klasse ableiten die dann die notwendigen Werte besitzt. Dann must du natürlich mit new und delete arbeiten.

    bis bald
    akari



  • Jo der Code ist gut, aber ich habs anders gelöst:

    // ID von Konto & Kategorie
            AnsiString KontoID, KategorieID;
                    // ID von Konto
                    SQLKonto->SQL->Clear();
                    SQLKonto->SQL->Add("SELECT ID,KONTONAME FROM KONTEN WHERE KONTONAME=:KONTONAME");
                            SQLKonto->Parameters->ParamByName("KONTONAME")->Value = ComboBox1->Text;
                    SQLKonto->Open();
                    KontoID = SQLKonto->FieldValues["ID"];
                    SQLKonto->Active = false;
    
                    // ID von Kategorie
                    SQLKategorie->SQL->Clear();
                    SQLKategorie->SQL->Add("SELECT ID,NAME FROM KATEGORIEEINAHMEN WHERE NAME=:NAME");
                            SQLKategorie->Parameters->ParamByName("NAME")->Value = ComboBox2->Text;
                    SQLKategorie->Open();
                    KategorieID = SQLKategorie->FieldValues["ID"];
                    SQLKonto->Active = false;
    

    Also später wenn er speichern will bediene ich mich an den 2 ADOQuery die da herumstehen und hau da meine SQL Statements rein und prüfe somit die ID die ich dann den 2 Variablen übergebe 🙂

    Trotzdem Big Thanks, kann geclosed werden.


Anmelden zum Antworten