2013-05-16 3 views
0

Я хочу создать базу данных с Qt, которая хранит имена и классы класса. Я представлял класс с именем tables. Когда я запускаю его, возникает ошибка и говорят, что «программа неожиданно остановилась» !!! В чем проблема? мой другой вопрос в том, как я могу сделать некоторые таблицы в одной базе данных. Как мне изменить свой класс (коды ниже)?Ошибка базы данных в Qt?

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); 
+0

Что говорит ваш отладчик? – cmannett85

+2

База данных не остается открытой: в 'tables :: tables' вы назначаете вновь созданное соединение локальной переменной (' db') вместо 'this-> db'. Но это не должно приводить к сбою. – alexisdm

+0

отладчик ничего не говорит .. программа вылетает –

ответ

1

Создано слишком много связей с базой данных. В конструкторе table класса устанавливается соединение с базой данных с помощью:

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

Вы создаете экземпляр класса table в main функции. В функции table_completer вы также создаете экземпляр класса table.

Также в функции table_completer вы создаете QSqlQuery. Он использует экземпляр QSqlDatabase, связанный с именем подключения по умолчанию, потому что вы не указываете имя явно. QSqlDatabase - как одиночный. Поскольку новое соединение имеет то же имя, что и старый, старый объект QSqlDatabase будет заменен новым объектом. QSqlQuery по-прежнему хранит указатель на старый QSqlDatabase, но он уже удален (уничтожен), поэтому он сбой.

Создание нового QSqlQuery в цикле работает, потому что оно использует действительный экземпляр QSqlDatabase (новый).

1

Второй запрос для связи с другим (потому что вы открыли еще одну базу данных, создавая другой экземпляр tables), так что вы должны получить еще один экземпляр QSqlQuery для его выполнения.

А также обратите внимание, что ваши команды SQL имеют синтаксические ошибки: После TABLE и INTO вы должны поставить пробел, чтобы предотвратить объединение его с именем таблицы, а также вы должны поместить строковые значения в одиночные кавычки:

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: Я исправил заявление, указанное fasked. Спасибо

+0

На самом деле это не так. Функция 'exec' полностью повторно используется в одном соединении. – fasked

+0

спасибо за отличный ответ ... –

+0

теперь как я могу сделать число таблиц в одной базе данных? –

Смежные вопросы