Seite 1 von 1

QSqlQuery

Verfasst: 24. Oktober 2010 21:42
von DBGTMaster
Hallo,

hätte paar Fragen zu der Klasse QSqlQuery:

1.) Kann ich irgendwie die fehlgeschlagene SQL ermitteln (für Debugging zwecke)? Ich finde nur Methoden, um die zuletzt erfolgreiche SQL zu erhalten.

2.) Muss ich bei jeder SQL nun per Hand überprüfen, ob diese auch erfolgreich war?

zB.:

Code: Alles auswählen

QSqlQuery query;
// ...
if (!query.exec()) throw SqlException(...);
Kann ich diesen Vorgang irgendwie automatisieren, so dass das überprüfen der SQL, ob erfolgreich automatisch geschieht und eventuell eine Exception geworfen wird?

Danke!

Verfasst: 24. Oktober 2010 21:54
von strige
Hi,

Code: Alles auswählen

QSqlQuery query;
query.exec("blabla");
QSqlError err = query.lastError();
qDebug() << err.text();
meintest du sowas?

Verfasst: 25. Oktober 2010 21:05
von DBGTMaster
strige hat geschrieben:Hi,

Code: Alles auswählen

QSqlQuery query;
query.exec("blabla");
QSqlError err = query.lastError();
qDebug() << err.text();
meintest du sowas?
Wie ich den letzten SQL Fehler ausgebe, ist mir auch soweit klar... Mir geht es eher um die Fehlerbehandlung.

Beispiel:

Code: Alles auswählen

    QSqlQuery insert;
    insert.prepare("INSERT INTO address (vorname, nachname, adresse, plz, ort, phone) VALUES (:vorname, :nachname, :adresse, :plz, :ort, :phone)");
    insert.bindValue(":vorname", _surname);
    insert.bindValue(":nachname", _lastname);
    insert.bindValue(":adresse", _address);
    insert.bindValue(":plz", _plz);
    insert.bindValue(":city", _city);
    insert.bindValue(":phone", _phone);

    if (!insert.exec()) {
        QMessageBox::critical(0, "Sql Fehler",
                              QString("Sql Fehler ist aufgetreten!<br><b>Zeile:</b> %1<br/><b>Datei:</b> %2<br><b>Error:</b> %3")
                              .arg(QString::number(__LINE__), __FILE__, insert.lastError().text() ) );
        
    }
Nach absetzen der SQL überprüfe ich, ob ein Fehler aufgetreten ist, wenn ja, teile ich es dem User mit...

Mir geht es um diesen Abschnitt:

Code: Alles auswählen

if (!insert.exec()) {
        QMessageBox::critical(0, "Sql Fehler",
                              QString("Sql Fehler ist aufgetreten!<br><b>Zeile:</b> %1<br/><b>Datei:</b> %2<br><b>Error:</b> %3")
                              .arg(QString::number(__LINE__), __FILE__, insert.lastError().text() ) );
        
    }
Diesen Code müsste ich nun bei jeder einzelnen SQL Query einbauen, was ich aber verhindern möchte...

Daher meine Frage, kann ich die Überprüfung der SQL und gegeben falls Fehler- Erzeugung automatisieren, so dass ich diese nach der Abfrage nicht immer wieder diese Abfrage durchführen muss?

Verfasst: 25. Oktober 2010 22:04
von Christian81
Die Frage ist - was willst Du erreichen? Reicht einfach ein 'return false' oder eine Logausgabe oder was? Irgendwo muss man den User ja benachrichtigen... Man kann auch um QSqlQuery.exec() eine Funktion drum rumbauen oder was auch immer. Hat aber alles nichts wirklich mit QSqlQuery sondern mit allgemeiner Fehlerbehandlung zu tun.

Verfasst: 25. Oktober 2010 22:11
von DBGTMaster
Christian81 hat geschrieben:Die Frage ist - was willst Du erreichen? Reicht einfach ein 'return false' oder eine Logausgabe oder was? Irgendwo muss man den User ja benachrichtigen... Man kann auch um QSqlQuery.exec() eine Funktion drum rumbauen oder was auch immer. Hat aber alles nichts wirklich mit QSqlQuery sondern mit allgemeiner Fehlerbehandlung zu tun.
Ich will eben den User benachrichten, dass etwas schief gelaufen ist...

Wenn meine Anwendung nun zB. 1000 SQL Abfragen beinhaltet, dann muss ich ja 1000 mal mein Konstrukt reinbauen, ob die SQL erfolgreich war, wenn nicht, dass benachrichtigen... Und genau das hier will ich verhindern...
Aber eine Funktion rumherum bauen klingt nicht schlecht...

bzw. andere frage:

gibt es eine etwas größere opensource anwendung mit datenbank- Anbindung, damit ich mir da mal ein bisschen ab schauen kann, wie das hier gelöst wurde?

lg

Verfasst: 26. Oktober 2010 10:13
von franzf
phpmyadmin, amarok, akonadi, nepomuk, joomla, ...
Die verwenden halt teilweise direkt die Schnittstelle ohne QtSql, bzw. sind php.

Verfasst: 26. Oktober 2010 10:24
von RHBaum
Glaub Teamspeak 3 verwendet Qt4 ... sogar im server (Pfui !).
die Einstellungen werden entweder in ner "richtigen DB" oder per default in ner SQLite DB abgelegt. DIe Chance dass die QtSQL verwenden iss sehr hoch ....
Ups, vergass, iss alles closed source, nix mit nachgucken ... :evil:

Aber vielleicht bei KMail, sollten aehnliche Dinge verwenden ...

Ciao ...

Verfasst: 26. Oktober 2010 16:52
von padreigh
Hatte ein ähnliches Problem in einer App die Zwingend eine DB-Connection brauchte, habe ich dort so gelöst:

Code: Alles auswählen

namespace SqlRelated {

    bool ensureConnection()
    {
        QSqlDatabase db;

        // if NO named connection present
        if (! QSqlDatabase::contains("myconnectionname"))
        {
            // create named database connection and get a handle on it
            db = QSqlDatabase::addDatabase("QMYSQL","myconnectionname");
        }
        else
        {
            db = QSqlDatabase::database("myconnectionname",false);
        }

        if (! db.isOpen())
        {
            // set up parameters
            db.setHostName("myhost");
            db.setPort(1234);
            db.setDatabaseName("mytablename");

            db.setUserName("myusername");
            db.setPassword("myuserpass");

            // try to open connection
            forever {
                if (! db.open()) // not able to open connection
                {
                    QMessageBox::StandardButton but;

                    but = QMessageBox::warning(0, "Error connecting to database",
                                               db.lastError().text().append("\n")
                                               .append("\nHOST:\t")
                                               .append(db.hostName())
                                               .append("\nPORT:\t")
                                               .append(QString::number(db.port()))
                                               .append("\nUSER:\t")
                                               .append(db.userName())
                                               .append("\nPASS:\t")
                                               .append(QString(db.password().size(),'*')),
                                               QMessageBox::Retry|QMessageBox::Cancel,
                                               QMessageBox::Retry);

                    // possible result buttons (retry through "forever")
                    if ( but == QMessageBox::Cancel)
                    {
                        QMessageBox::critical(0, "Critical Error:",
                                              "Unable to connect to database.\n\n"
                                              "No data == no functionality => "
                                              "Aborting program.",
                                              QMessageBox::Abort) ;
                        qApp->exit(-1);
                    }
                }
                // OPEN
                else
                {
                    break; // break forever statement
                }
            }
        }
        return true;
    }


    void debugSqlError(const QSqlQuery & sqlQuery)
    {
        debugSqlError(sqlQuery.lastError());
    }

    void debugSqlError(const QSqlError & sqlError)
    {
        QString text = sqlError.text()
                       .append("\n\n\n\n")
                       .append("Error #\t").append(QString::number(sqlError.number()))
                       .append("\nType   \t");

        switch (sqlError.type())
        {
        case 0: text.append("No error."); break;
        case 1: text.append("Connection error."); break;
        case 2: text.append("SQL statement syntax error."); break;
        case 3: text.append("Transaction failed error."); break;
        case 4: text.append("Unknown error."); break;
        }

        QMessageBox::warning(0,"DEBUG Sql-Error", text,QMessageBox::Ok,QMessageBox::Ok);
    }
};

using SqlRelated::debugSqlError;
using SqlRelated::ensureConnection;

Code: Alles auswählen

    // irgendwo im Konstruktor meiner DB-Benutzenden Klasse:
    static bool ensuredConnect = SqlRelated::ensureConnection();
    if (! ensuredConnect) { qDebug() << "rausoptimierung verhindern, hier kommet man aber nie hin ...";}

Code: Alles auswählen

    // irgendwo beim Querying:
    QSqlQuery queryChildData = db.exec(mChildQuery);
    // query was successfull ?
    if (! queryChildData.isActive())
    {
        // output the error and stop querying
        debugSqlError(queryChildData);
        return;
    }
Du solltest bei 1000 SqlQueries vielleicht sicherstellen das der User eine Möglichkeit zum Abbruch hat ... ich hasse es 1000 Query-Fehler wegdrücken zu müssen bevor der "query" Teil des Codes zuende ist ...