2013-05-16 2 views
0

클래스의 이름과 등급을 저장하는 Qt 데이터베이스를 만들고 싶습니다. tables이라는 클래스를 나타냅니다. 실행할 때 오류가 발생하고 "프로그램이 예기치 않게 중지되었습니다"라는 메시지가 나타납니다. 무엇이 문제입니까? 다른 질문은 하나의 데이터베이스에서 일부 테이블을 만들 수 있습니다. 어떻게 내 수업 (아래 코드)을 변경해야합니까? (당신이 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'에서 새로 생성 된 연결을'this-> db' 대신에 지역 변수 ('db')에 할당하고 있습니다. 하지만 이로 인해 충돌이 발생해서는 안됩니다. – alexisdm

+0

디버거는 아무 것도 말하지 않습니다 .. 프로그램이 충돌합니다 –

답변

1

데이터베이스와의 연결이 너무 많습니다. table 클래스의 생성자에서 당신이 사용하는 데이터베이스와의 연결을 설정 :

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

당신은 main 기능에 table 클래스의 인스턴스를 만듭니다. table_completer 함수에서 table 클래스의 인스턴스를 만들 수도 있습니다.

table_completer의 경우도 QSqlQuery을 작성하십시오. 이름을 명시 적으로 지정하지 않으므로 QSqlDatabase 인스턴스가 기본 연결 이름과 연결됩니다. QSqlDatabase은 (는) 싱글 톤과 같습니다. 새 연결 이름이 이전 연결 이름과 동일하기 때문에 이전 QSqlDatabase 개체가 새 개체로 바뀝니다. QSqlQuery은 여전히 ​​이전 QSqlDatabase에 대한 포인터를 저장하지만 이미 제거 (삭제)됩니다. 따라서 충돌합니다.

유효한 QSqlDatabase (새 인스턴스) 인스턴스를 사용하기 때문에 루프에 새로운 QSqlQuery이 작성됩니다.

1

두 번째 쿼리는 다른 연결, 그래서 당신은 그것을 실행하기위한 QSqlQuery의 다른 인스턴스를 얻을 수있다. 당신이 공간을 넣어야 할 TABLEINTO 후 테이블 이름과 결합 방지하고 또한 작은 따옴표로 문자열 값을 추가해야한다 :

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+")"); 
또한

그리고

은 SQL 명령 구문 오류가 있습니다

편집 : 나는 fasked으로 표시된 진술을 수정했습니다. 감사합니다

+0

실제로 사실이 아닙니다. 'exec' 함수는 한 연결 내에서 완전히 재사용 가능합니다. – fasked

+0

우수한 답변을 주셔서 감사합니다 ... –

+0

지금은 어떻게 하나의 데이터베이스에 테이블의 번호를 만들 수 있습니까? –