2017-12-18 109 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();