0

I wanna make a database with Qt that stores the names and grades of a class.I represented a class named tables.when I run it ,an error happens and say "the program stopped unexpectedly"!!!what is the problem? my other question is that how can I make some tables in one database .how should I change my class(the codes below)?

database.h:

#ifndef DATABASE_H
#define DATABASE_H

#include <QtSql>
#include <QString>
#include <random>

class tables
{

private:
    QString name;
    QString table_name;
    QSqlDatabase db;

public:
    tables(QString);
    tables(QString,QString);
    void table_completer(int);
    QString rand_name();
    QString make_string(int);
    ~tables();
};

tables :: tables(QString nt)
{
    table_name = nt;
}

tables :: tables(QString n,QString nt)
{
    name = n;
    table_name = nt;
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(name);
    db.open();
}

QString tables :: rand_name(){
    QString a = "abcdefghijklmnopqrstuvwxyz";
    QString s = "";
    int b = rand()%3 + 4;
    for(int i=0;i<b;i++){
        int n = rand()%25;
        s += a[n];
    }
    return s;
}

QString tables :: make_string(int num)
{
    QString result;
    result.append(QString("%1").arg(num));
    return result;
}

void tables :: table_completer(int students_numbers)
{
    QSqlQuery query;
    query.exec("CREATE TABLE"+table_name+"(firstname text,lastname text,math int,physics int,litrature int,chemistry int);");
    tables t(name,table_name);
    for(int i=0;i<students_numbers;i++){
        int a = rand()%20;
        QString e = t.make_string(a);
        int b = rand()%20;
        QString f = t.make_string(b);
        int c = rand()%20;
        QString g = t.make_string(c);
        int d = rand()%20;
        QString h = t.make_string(d);
        query.exec("INSERT INTO"+table_name+"VALUES("+t.rand_name()+","+t.rand_name()+","+e+","+f+","+g+","+h+")");
    }
}

tables :: ~tables()
{
    db.close();
}



#endif // DATABASE_H

main:

tables ab("mydatabase.db","class1");
ab.table_completer(30);
5
  • What does your debugger say? Commented May 16, 2013 at 14:42
  • 2
    The database doesn't stay open: in tables::tables, you are assigning the newly created connection to a local variable (db) instead of this->db. But this shouldn't cause a crash. Commented May 16, 2013 at 14:48
  • the debugger doesn't say anything..the program crashes Commented May 16, 2013 at 14:52
  • So your program crashes before main()? Commented May 16, 2013 at 15:03
  • this is exactly my question that why it crashes???!!!! Commented May 16, 2013 at 15:14

2 Answers 2

1

There are too many connections with database are created. In constructor of table class you establish connection with database using:

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(name);
db.open();

You create instance of table class in main function. In table_completer function you also create instance of table class.

Also in function table_completer you create QSqlQuery. It uses QSqlDatabase instance associated with default connection name because you don't specify the name explicitly. QSqlDatabase is like singleton. Because the new connection has the same name as the old one, the old QSqlDatabase object will be replaced with the new object. QSqlQuery still stores the pointer to the old QSqlDatabase but it is removed (destroyed) already - so it will crash.

Creation of new QSqlQuery in loop works because it uses valid QSqlDatabase (the new one) instance.

Sign up to request clarification or add additional context in comments.

Comments

1

The second query is for another connection (because you've opened another database by creating other instance of tables), so you have to get another instance of QSqlQuery for executing it.

And also note that your sql commands have syntax errors: After TABLE and INTO you have to put a space to prevent combining it with the table name and also you have to put the string values into single quotes:

query.exec("CREATE TABLE "+table_name+"(firstname text,lastname text,math int,physics int,litrature int,chemistry int);");
tables t(name,table_name);
QSqlQuery newQuery;
...

newQuery.exec("INSERT INTO "+table_name+"VALUES('"+t.rand_name()+"','"+t.rand_name()+"',"+e+","+f+","+g+","+h+")");

EDIT: I've corrected the statement noted by fasked. Thanks

2 Comments

It's not actually true. exec function is fully reusable within one connection.
@CasillassReal In order to work with one database you should call QSqlDatabase::open one time in one thread. You can just do it in main function. You should not create new connection to make new query.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.