1. 程式人生 > >QT資料庫操作QSqlQuery

QT資料庫操作QSqlQuery

資料庫對大多數應用來說,大概是必備吧。如何對資料庫進行增刪改查等操作也許就是關鍵了。在QT中如何對資料庫進行這些操作呢?QSqlQuery類可以完成!如何使用它呢?看下面吧!(對資料庫操作前需要先連線資料庫,連線資料庫請先檢視資料庫連線

QSqlQuery

QSqlQuery支援DML(data manipulation language)語法,如:SELECT, INSERT,UPDATE and DELETE;也支援DDL(data definition language)語法,如:CREATE TABLE;還支援非標準的特點資料庫命令,如:SET DATESTYLE=ISO

 for PostgreSQL。
注意:在QSqlQuery物件建立前,開啟資料庫,且保持其開啟狀態,否則將出現未定義行為。

執行操作

bool QSqlQuery::exec()
bool QSqlQuery::exec(const QString & query)

執行資料庫操作,將重置lastError(),並將使isActive()返回true,直到其完成操作。
第一個函式使用前序使用bool QSqlQuery::prepare(const QString & query)準備操作語句,第二個函式則直接使用操作語句。

//方式一:
QSqlQuery query;
query.prepare("INSERT INTO person (id, forename, surname) "
              "VALUES (:id, :forename, :surname)");
query.bindValue(":id", 1001);
query.bindValue(":forename", "Bart");
query.bindValue(":surname", "Simpson");
query.exec();  

//方式二:
QSqlQuery query;
query.exec("INSERT INTO employee (id, name, salary) "
           "VALUES (1001, 'Thad Beaumont', 65000)");

注意:

  • 當QSQLDatabase使用了連線名,即如addDatabase("QMYSQL","connName")時,需使用建構函式QSqlQuery(QSqlDatabase db)
  • 一些資料庫會延遲prepare()直到呼叫exec(),這將導致不能正確執行。
  • 在SQLite中,同時執行超過一條語句將導致函式返回false。

結束操作

void QSqlQuery::finish()

該函式通常無需呼叫,除非同一QSqlQuery物件間隔一段時間再使用時,呼叫該函式可釋放資源。呼叫該函式將使isActive()返回false

狀態查詢

bool QSqlQuery::isActive() const

當QSqlQuery物件成功exec(),且未結束時,返回true。
注意:正在活動SELECT查詢,將導致commit()rollback()失敗。

操作查詢記錄

bool QSqlQuery::next()
bool QSqlQuery::previous()
bool QSqlQuery::first()
bool QSqlQuery::last()
bool QSqlQuery::seek(int index, bool relative = false)

只向前取資料

void QSqlQuery::setForwardOnly(bool forward)

當forward為true時,只有next()seek()操作可用,且可以減少快取的使用,還可以提高某些資料庫的效能。在QSqlQuery物件執行後設置將導致結果未定義,或崩潰。

讀取獲得的資料

QVariant QSqlQuery::value(int index) const

例:

QSqlQuery query("SELECT country FROM artist");
while (query.next()) {
    QString country = query.value(0).toString();
    doSomething(country);
}

注意:SELECT * FROM table的字元返回是不確定的,不宜使用value(0)等。可使用record().indexOf()將欄位名轉換為索引值。

QSqlQuery query("SELECT * FROM artist");
int fieldNo = query.record().indexOf("country");
while (query.next()) {
    QString country = query.value(fieldNo).toString();
    doSomething(country);
}

執行效果

int QSqlQuery::numRowsAffected() const

當non-SELECT時,使用上面的函式,當SELECT時,需使用下面的函式

int QSqlQuery::size() const

使用isSelect()判斷是否為SELECT語句。

繫結佔位符變數

void QSqlQuery::bindValue(const QString & placeholder, const QVariant & val, QSql::ParamType paramType = QSql::In)

Qt支援的繫結方式

  • 名稱繫結到名稱佔位符

    QSqlQuery query;
    query.prepare("INSERT INTO person (id, forename, surname) "
                  "VALUES (:id, :forename, :surname)");
    query.bindValue(":id", 1001);
    query.bindValue(":forename", "Bart");
    query.bindValue(":surname", "Simpson");
    query.exec();
    
  • 位置繫結到名稱佔位符

    QSqlQuery query;
    query.prepare("INSERT INTO person (id, forename, surname) "
                  "VALUES (:id, :forename, :surname)");
    query.bindValue(0, 1001);
    query.bindValue(1, "Bart");
    query.bindValue(2, "Simpson");
    query.exec();
    
  • 繫結值到位置佔位符1

    QSqlQuery query;
    query.prepare("INSERT INTO person (id, forename, surname) "
                  "VALUES (?, ?, ?)");
    query.bindValue(0, 1001);
    query.bindValue(1, "Bart");
    query.bindValue(2, "Simpson");
    query.exec();
    
  • 繫結值到位置佔位符2

    QSqlQuery query;
    query.prepare("INSERT INTO person (id, forename, surname) "
                  "VALUES (?, ?, ?)");
    query.addBindValue(1001);
    query.addBindValue("Bart");
    query.addBindValue("Simpson");
    query.exec();
    
  • 繫結值到儲存器(不完全支援)

    QSqlQuery query;
    query.prepare("CALL AsciiToInt(?, ?)");
    query.bindValue(0, "A");
    query.bindValue(1, 0, QSql::Out);
    query.exec();
    int i = query.boundValue(1).toInt(); // i is 65
    

    注意:未繫結的引數,將保持原來的值。