MySQL Abfrage in einen Wert speichern und damit arbeiten

Alles rund um die Programmierung mit Qt
Antworten
Tanktiger
Beiträge: 21
Registriert: 4. März 2010 10:51
Kontaktdaten:

MySQL Abfrage in einen Wert speichern und damit arbeiten

Beitrag von Tanktiger »

Hallo

Falls es zu diesem Thema schon ein Thread gibt bitte ein Link dazu poste. Ich habe nichts hilfreiches mit der Suche gefunden.

Zu meinem Problem.
Ich les in QT mit der SELECT Anfrage einen Wert aus meiner datenbank aus. Jetzt soll dieser ausgelesen wert in ein String gespeichert werden.
Diesen String setzt ich dann in eine andere SQL Anfrage wieder ein um aus einer anderen Tabelle einen Wert zu bekommen.
Das mach ich so weil der Nutzer den ersten Wert eingeben kann und das ist eine ID aus einer Relationstabelle. Somit les ich erst da den wert aus um den gleichen Wert dann aus einer anderen Tabelle zu benutzen.

Mein Code bis jetzt:

Code: Alles auswählen

void SQLQuery::Fdelete(QString RFA)
{
myDB.open();
 if(myDB.isOpen())
 {
     int qindex;
     QSqlQuery query;
//Fragen auslesen
             query.prepare("SELECT F_ID FROM RelQuestAnswer WHERE rfa_id=:q");
             query.bindValue(":q", RFA);
             query.exec();

             if(query.isActive())
             {
                 query.next();
                 qindex = query.value(0).toInt();
             }
             if(qindex<1)
             {

                 query.prepare("Delete Questions From Questions WHERE   f_id=:q");
                 query.bindValue(":q", qindex);
                 query.exec();
                 query.prepare("SELECT F_ID FROM Questions WHERE Questions=:q");
                 query.bindValue(":q", RFA);
                 query.exec();
                 if(query.isActive()){
                     query.next();
                     qindex=query.value(0).toInt();
                 }
             }

 }
else
    {
    qDebug( "Could not open database" );

    }
myDB.close();

 }
Wie ihr seht will ich das der User was löschen kann wer einen bestimmten wert einträgt. Dieser Wert darf nur eine Zahl sein.

Ich danke schon mal für jede Hilfe
mgh
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

1. query.isActive() mit query.next() austauschen. Das folgende query.next() kann dann wegfallen.
2. Eine einheitlichere SQL-Syntax-Formatierung hilft bei der Übersicht.
3. Dein eigentliches Problem ist nicht verständlich.
Tanktiger
Beiträge: 21
Registriert: 4. März 2010 10:51
Kontaktdaten:

Beitrag von Tanktiger »

1. Hilf iwie nicht
2. ja die Formatierung müsst man mal überarbeiten
3. Da das ja vom aufbau her richtig zu sein scheint wird aber die Frage nicht gelöscht.

Ich beschreib noch mal:
Ich hab Fragen mit 4 verschiedenen Antworten. Diese Fragen mit den dazu gehörigen Antworten sind über eine Relationstabelle verbunden um die richtigen Antworten für die Fragen zu sehen. Da eine Antwort für mehrere Fragen verwendet werden kann und da diese Antwort ja bei einigen Fragen richtig und bei anderen Falsch sein kann.
Naja zumindestens soll der Nutzer die ID von der Relation eingeben und dann soll das Programm aus der Relationstabelle sich die id der frage holen. Diese soll dann in einem Wert zwischengespeichert werden. Dann in einer neuen Abfrage soll die Frage gelöscht werden in der eigenen Tabelle gelöscht werden. Danach will ich dann das er auch noch die Relation löscht damit die nicht mehr vorhanden ist. Die Antworten sollen aber bestehen bleiben.

Ist es jetzt einigermaßen verständlich?^^
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Tanktiger hat geschrieben: Ist es jetzt einigermaßen verständlich?
Die Aufgabe ist verständlich, aber nicht das Problem. Mit qDebug() oder dem Debugger solltest du den Programmfluss verifizieren können und uns dann schreiben, an welcher Zeile das Verhalten anderst ist als von dir erwartet.
Tanktiger hat geschrieben:1. Hilf iwie nicht
Was genau hilft nicht? Was genau an der Doku zu "isActive()" (http://doc.trolltech.com/4.6/qsqlquery.html#isActive) ist unklar? Ich meine: es muss doch einen Grund geben, warum du dort "isActive()" geschrieben hast... oder?
Tanktiger
Beiträge: 21
Registriert: 4. März 2010 10:51
Kontaktdaten:

Beitrag von Tanktiger »

Code: Alles auswählen

             query.prepare("SELECT F_ID FROM RelQuestAnswer WHERE rfa_id=:q");
             query.bindValue(":q", RFA);
             query.exec();

             if(query.next())
             {
                 qindex = query.value(0).toInt();
             }
             if(qindex>1)
             {

                 query.prepare("Delete Questions From Questions WHERE f_id=:q");
                 query.bindValue(":q", qindex);
                 query.exec();
Das was an dier Stelle passieren soll, passiert nicht. Das ist grade das was mir nicht verständlich ist.
Mit QDebug etc find ich nix hilfreiches.
Die Doku hab ich mir auch angeguckt aber find auch da nichts hilfreiches...
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Tanktiger hat geschrieben:

Code: Alles auswählen

             query.prepare("SELECT F_ID FROM RelQuestAnswer WHERE rfa_id=:q");
             query.bindValue(":q", RFA);
             query.exec();

             if(query.next())
             {
                 qindex = query.value(0).toInt();
             }
             if(qindex>1)
             {

                 query.prepare("Delete Questions From Questions WHERE f_id=:q");
                 query.bindValue(":q", qindex);
                 query.exec();
Das was an dier Stelle passieren soll, passiert nicht. Das ist grade das was mir nicht verständlich ist.
Mit QDebug etc find ich nix hilfreiches.
Die Doku hab ich mir auch angeguckt aber find auch da nichts hilfreiches...
Also an deiner Stelle würde ich mir jetzt den Wert von qindex ausgeben, und anschließend die sql-query mit einem Frontend deiner Wahl auf der Datenbank absetzen.

Oder anders: Was soll denn passieren?
Tanktiger
Beiträge: 21
Registriert: 4. März 2010 10:51
Kontaktdaten:

Beitrag von Tanktiger »

Hab ich doch oben beschrieben

Es soll mittels einer Select abfrage ein wert ausgelesen werden und mit diesem Wert soll dann ein anderer wert in der Datenbank gelöscht werden.
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Tanktiger hat geschrieben:Hab ich doch oben beschrieben

Es soll mittels einer Select abfrage ein wert ausgelesen werden und mit diesem Wert soll dann ein anderer wert in der Datenbank gelöscht werden.
Ja und was geht nicht?
Tanktiger
Beiträge: 21
Registriert: 4. März 2010 10:51
Kontaktdaten:

Beitrag von Tanktiger »

das löschen geht nicht es wird der wert selected aber nicht gelöscht!
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Tanktiger hat geschrieben:das löschen geht nicht es wird der wert selected aber nicht gelöscht!
Lass dir dochmal query.lastQuery() sowie query.lastError().text() ausgeben.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Ich hab auch keine AHnung, wie die einzelnen Datenbanktreiber bei query.prepare() reagieren, wenn der query schon benutzt ist (dein query ist ja noch aktiv). Versuchs doch einfach mal mit nem neuen QSqlQuery-Objekt fürs Löschen.
Roedi
Beiträge: 4
Registriert: 12. Juli 2010 11:38

Beitrag von Roedi »

Tanktiger hat geschrieben:

Code: Alles auswählen

             query.prepare("SELECT F_ID FROM RelQuestAnswer WHERE rfa_id=:q");
             query.bindValue(":q", RFA);
             query.exec();

             if(query.next())
             {
                 qindex = query.value(0).toInt();
             }
             if(qindex>1)
             {

                 query.prepare("Delete Questions From Questions WHERE f_id=:q");
                 query.bindValue(":q", qindex);
                 query.exec();
Das was an dier Stelle passieren soll, passiert nicht. Das ist grade das was mir nicht verständlich ist.
Mit QDebug etc find ich nix hilfreiches.
Die Doku hab ich mir auch angeguckt aber find auch da nichts hilfreiches...
Probier mal bei dem Abschnitt

Code: Alles auswählen

                 query.prepare("Delete Questions From Questions WHERE f_id=:q");
diesen hier

Code: Alles auswählen

                 query.prepare("Delete From Questions WHERE f_id=:q");
Tanktiger
Beiträge: 21
Registriert: 4. März 2010 10:51
Kontaktdaten:

Beitrag von Tanktiger »

ich hab noch mal nachgeschaut und herausgefunden das der wert nicht übergeben wird.
Das QString RFA ist leer wenn es ankommt.
Der Code

Code: Alles auswählen

    SQLQuery test;
    test.Zeig();

    qwdte = new QWidget();

    qlq = new QLabel("RFA_ID", this);
    qleq = new QLineEdit(this);

    qpbTsave = new QPushButton("Löschen", this);
    connect(qpbTsave, SIGNAL(clicked()), this, SLOT(slotFhinzu()));
    qPBClose = new QPushButton("Abbrechen", this);
    connect(qPBClose, SIGNAL(clicked()), qwdte, SLOT(close()));

    qglTest =  new QGridLayout();
    qglTest->addWidget(qlq,0,0);
    qglTest->addWidget(qleq,0,1);
    qglTest->addWidget(qpbTsave,1,0);
    qglTest->addWidget(qPBClose,1,1);
    qwdte->setLayout(qglTest);

    qwdte->show();

    SQLQuery fdelete;
    fdelete.Fdelete(qleq->text());
Das steht in der Methode die aufgerufen wird wenn ich den Button fragen löschen anklick.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Witzbold :P
Der Code bringt uns gar nix, da der interessante Code in deinen Methoden von "SQLQuery" versteckt ist... Wir wissen auch nicht was im qleq->text() steht. Das eigentliche Problem ist aber, dass show() nicht blockiert ;) Deine Methode rasselt durch, und uninitialisiert ist so ein LineEdit natürlich leer. Lösung: qwdte wird zum QDialog, der mit exec() gestartet wird. exec() blockiert, und sobald der Dialog geschlossen ist kommst du auch an die (korrekten) Werte.

Ein paar Sachen noch:
Es ist nicht schön und schon gar nicht benutzerfreundlich, wenn der User selber (abolut undurchsichtige und abstrakte!) IDs einer SQL-Tabellen-Relation selber (!) eingeben muss (so hast du es bisher geschildert). Pack doch diese ganzen Sachen in ein schönes Interface, welches z.B. über CheckBoxen das Löschen einfach gestaltet. So werden auch gleich viele Bedienungsfehler ausgeschlossen.

So wie du deine Widgets, die in dem Dialog landen, initialisierst, ist es unsinnig. "this" als parent übergeben, dann aber wieder in ein Layout packen, was dazu führt, dass das Widget (z.B. dein QLabel qlq) einen neuen parent bekommt.

Du hast da ein perfektes MemoryLeak gebastelt! Die Member werden bei jedem Click neu initialisiert aber nie gelöscht, ein Zerstören im Destruktor zerstört nur das zuletzt erzeugte, alle anderen sterben ohne Destruktoraufruf durch Speicherbereinigung des Betriebssystems (wenn das OS so etwas auch macht). Und nein, die QObject-Hierarchie greift hier nicht, qlq &CO sind children von dem jeweils neu erzeugten qwdte (resp. dem Layout).
Tanktiger
Beiträge: 21
Registriert: 4. März 2010 10:51
Kontaktdaten:

Beitrag von Tanktiger »

ok das mit QObject werd ich mal ausprobieren. dank dir

Ich weiß das das nicht benutzerfreundlich ist^^ Ich wollt es erst mal so zum testen nehmen.
Die Idee mit dem Interface hat ich auch, bloß an den Stellen mit den Checkboxen hackts. Wie krieg ich das denn hin wenn er z.B. die Checkbox fürs löschen einen haken macht, dass dann auch die Relation mit Frage gelöscht wird? Kann mir das mal bitte jemand erklären oder nen link dazu geben?
Danke^^
Antworten