Seite 1 von 1

QSqlDatabase Fehlerbehandlung

Verfasst: 26. November 2010 15:04
von DBGTMaster
Hallo,

hab heute ein bisschen darüber nachgedacht, wie man am besten mit der QSqlDatabase Klasse die Fehlerbehandlung im Falle einer fehlerhaften SQL behandelt.

Hab mich nun dazu entschieden, eine eigene Klasse zu verwenden, welche die QSqlDatabase Klasse verwaltet, und welche ein Signal zur Verfügung stellt, welches geschmissen wird, sobald ein fehlerhaften SQL Statement, Verbindungsfehler etc. auftritt:

Code: Alles auswählen

#ifndef DATABASE_H
#define DATABASE_H

#include <QObject>

#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>

class Database : public QObject
{
    Q_OBJECT

public:
    // Fehler- Meldungen:
    enum ErrorTypes {
        ERROR_SQL_STATEMENT,        // Wenn ein SQL fehlgeschlagen ist.
        ERROR_CONNECT,              // Wenn beim verbinden zur DB ein Fehler auftritt.
        ERROR_TRANSACTION,          // Wenn Transaktion fehlgeschlagen ist.
        ERROR_UNKNOWN               // Genaue Fehlerursache ist nicht bekannt.
    };

private:
    // Verbindung zur Datenbank:
    QSqlDatabase _dbConnection;

public:
    explicit Database(QSqlDatabase &dbConnection, QObject *parent = 0);

    // Verbindungs- Daten zur Datenbank setzen:
    void setHostname(const QString &hostname);
    void setUsername(const QString &username);
    void setPassword(const QString &password);
    void setDatabase(const QString &database);

    // Zur Datenbank verbinden:
    bool connect();
    bool connect(const QString &hostname, const QString &username, const QString &password, const QString &database);

    // Führt eine SQL aus:
    QSqlQuery query(const QString sql, const int line, const char *file, const bool throwError = true);

    // Fehlerbehandlung:
    QString lastErrorText();
signals:
    // Signal, wenn ein Fehler aufgetreten ist:
    void error(const int line, const char *file, ErrorTypes error, const QString errorMessage, const QString sql);

public slots:

};

#endif // DATABASE_H
Mir würd interessieren, wie ihr das lösen würdet? Gibts bessere Wege?

Verfasst: 26. November 2010 16:12
von Troll.Soft
moin auch,
ich habe alle meine queries in eine eigene Funktion gesteckt, die true oder false zurückliefert. Ist mir so am sympatischsten.
tschüß
Troll.Soft

P.S.: In Deinem Code ist mir nicht ganz klar, wie und wo Du die Fehlercodes emittest.

Verfasst: 27. November 2010 22:08
von DBGTMaster
Guten Abend,

Überprüfung, ob Befehl erfolgreich:

Code: Alles auswählen

QSqlQuery Database::query(const QString sql, const char *file, const int line, const bool throwError) {

    QSqlQuery query = _dbConnection.exec(sql);

    // Soll im Falle eines Fehlers eine Exception geworfen werden?
    if (throwError) {
        if (_dbConnection.lastError().isValid()) {
            emit error(file, line, ERROR_SQL_STATEMENT, _dbConnection.lastError(), sql);
        }
    }
Dann wird in der Hauptanwendung noch ein connect des Signales durchgeführt:

Code: Alles auswählen

...
    QSqlDatabase qDb = QSqlDatabase::addDatabase("QSQLITE");
    Database db( qDb );

    connect(&db, SIGNAL(error(const char*,int,Database::ErrorTypes,QSqlError,QString)),
            this, SLOT(showSqlError(const char*,int,Database::ErrorTypes,QSqlError,QString)));

...

// SLOT:
void MainWindow::showSqlError(const char *file, int line, Database::ErrorTypes, QSqlError error, QString sql) {

    // Fehlermeldungs- Text zusammenbauen:
    QString errorText(
            QString("File: '%1'<br>Line: %2<br>Database error: %3<br>Driver error: %4<br>SQL: %5").arg(file, QString::number(line), error.databaseText(), error.driverText(), sql)
           );

    QMessageBox::critical(this, "Program error - SQL execution failed!", errorText);
}

Verfasst: 27. November 2010 22:18
von dazedly
Warum schreibst du in den Constructor von deinem errorText Denn noch einen QString. Arbeite doch gleich mit errorText.

Verfasst: 28. November 2010 08:40
von DBGTMaster
dazedly hat geschrieben:Warum schreibst du in den Constructor von deinem errorText Denn noch einen QString. Arbeite doch gleich mit errorText.
weil ich mittels qsqlerror nicht die ausgeführte sql ermitteln kann, oder gibts da doch ne möglichkeit?