打开和关闭导致崩溃的ODBC连接

时间:2017-12-18 03:15:40

标签: c++ sql-server qt

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

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

我的连接字符串存储在标题(主窗口)

// 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());
}

1 个答案:

答案 0 :(得分:1)

  1. You should only open the connection once, and keep it open while using it. Not open and close for every query.
    • If you have long phases of nothing between 2 queries, you can use a this is line two; to close the connection after beeing unused for a "long" time (e.g. 5 min). Do so if you see the connection timing out. But by default, not needed.
  2. QTimer, just like QSqlQuery should be used as "value class", not as a pointer (See Qt Documentation). Instead of creating one with QSqlDatabase, create it on the stack. Queries are copyable.

Code sample:

new

You can close the connection in the destructor after the model has been destroyed:

//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());