2017-12-18 108 views
0

我编写了一个使用SQLite数据库的程序,它正常工作。现在我试图使它与SQL Server一起工作。该应用程序在启动时崩溃,我已经解决了这是关于打开和关闭数据库连接的方式。我真的不确定是否需要打开连接一次,或者每次运行查询时是否应打开并关闭连接?还建议在执行后删除指向该查询的指针?删除conn.connOpen和conn.connClose部分将使程序运行,但其不稳定。QT C++打开和关闭导致崩溃的ODBC连接

有关如何处理连接的任何建议(因为我有很多按钮执行不同的查询),我们非常感谢。

我的连接字符串存储在一个头(主窗口)

// mainwindows.h 

public: 
QSqlDatabase mydb; 
void connClose() 
{ 
    connected = false; 
    mydb.close(); 
    mydb.QSqlDatabase(); 
    mydb.removeDatabase(QSqlDatabase::defaultConnection); 
} 

bool connOpen() 
{ 
    if(!connected) 
    { 
     mydb = QSqlDatabase::addDatabase("QODBC"); //uses dsn, connects fine. 
     mydb.setDatabaseName("Test"); 
     if(!mydb.open()) 
     {      
      qDebug() << mydb.lastError().text(); 
      connected = false; 
     } 
     else 
     { 
      qDebug()<<"Connected"; 
      connected = true; 
     } 
    } 
    return connected; 
} 

private: 
static bool connected; 

这里是我如何调用我的.cpp文件查询的例子;

Financelog::Financelog(QWidget *parent) : 
QDialog(parent), 
ui(new Ui::Financelog) 
{  
    ui->setupUi(this); 
    setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint | 
        Qt::WindowContextHelpButtonHint | Qt::WindowMinMaxButtonsHint); 

    MainWindow conn; // call the connection string 
    if(!conn.connOpen()) 
     ui->label_sec_status->setText("<font color='red'>Failed to Open Database</font>"); 
    else 
     ui->label_sec_status->setText("<font color='green'>Connected</font>"); 

    QSqlQueryModel * modal=new QSqlQueryModel(); 

    conn.connOpen(); // ---- **DO I NEED THIS? REMOVING STOPS CRASHES.** 

    QSqlQuery* qry=new QSqlQuery(conn.mydb); 

    qry->prepare("select DEAL_DATE, DEAL_NUMB, CCICOMM, CCIPREM, INCOME from LOG");  
    qry->exec(); 
    modal->setQuery(*qry); 
    ui->tableView->setModel(modal); 
    ui->tableView->resizeColumnsToContents(); 
    ui->tableView->setAlternatingRowColors(true); 
    ui->tableView->setStyleSheet("alternate-background-color: #009900; background-color: #006600;"); 

    //delete qry; **DO I NEED THIS TO RELEASE MEMORY?** 

    conn.connClose(); // **DO I NEED THIS?** 

    qDebug() << (modal->rowCount()); 
} 
+0

SQLite中没有用户名或密码,但在其他数据库(如果有的话),你必须传递这些参数:'QSqlDatabase db = QSqlDatabase :: addDatabase(“QODBC”); db.setHostName(“你的数据库的IP地址”); db.setHostName db.setDatabaseName(“database name”); db.setUserName(“your user”); db.setPassword(“your password”); bool ok = db.open();' – eyllanesc

+0

谢谢,但我可以连接到数据库好。在准备和执行查询时,由于打开和关闭连接而导致崩溃。删除conn.connOpen和conn.connClose修复崩溃,但我不知道为什么。看起来是特定于SQL Server驱动程序 – FrostK

回答

0
  1. 您应该只打开连接一次,而使用它保持打开状态。 不是为每个查询打开和关闭。
    • 如果在2个查询之间没有长时间的空闲阶段,则可以使用QTimer在“长时间”(例如5分钟)未使用之后关闭连接。如果您看到连接超时,请这样做。但默认情况下,不需要。
  2. QSqlQuery,就像QSqlDatabase应被用作 “值类”,而不是一个指针(见Qt Documentation)。不要用new创建一个,请在堆栈上创建它。查询是可复制的。

代码示例:

//only once, i.e. in your windows constructor 
conn.connOpen(); 

//set up the model 
QSqlQueryModel * modal=new QSqlQueryModel(); 

QSqlQuery qry(conn.mydb); 

qry.prepare("...");  
qry.exec(); 
modal->setQuery(qry); 
//... 

// do not delete the query or close the database connection! 

qDebug() << (modal->rowCount()); 

可以后关闭连接在析构函数模型已经被破坏:

model->deleteLater(); 
conn.connClose();