QT C++打开和关闭导致崩溃的ODBC连接
问题描述:
我编写了一个使用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());
}
答
- 您应该只打开连接一次,而使用它保持打开状态。 不是为每个查询打开和关闭。
- 如果在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();
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
谢谢,但我可以连接到数据库好。在准备和执行查询时,由于打开和关闭连接而导致崩溃。删除conn.connOpen和conn.connClose修复崩溃,但我不知道为什么。看起来是特定于SQL Server驱动程序 – FrostK