QT資料庫操作QSqlQuery
資料庫對大多數應用來說,大概是必備吧。如何對資料庫進行增刪改查等操作也許就是關鍵了。在QT中如何對資料庫進行這些操作呢?QSqlQuery類可以完成!如何使用它呢?看下面吧!(對資料庫操作前需要先連線資料庫,連線資料庫請先檢視資料庫連線)
QSqlQuery
QSqlQuery支援DML(data manipulation language)語法,如:SELECT,
INSERT,UPDATE and DELETE
;也支援DDL(data definition language)語法,如:CREATE
TABLE
;還支援非標準的特點資料庫命令,如:SET DATESTYLE=ISO
注意:在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
注意:未繫結的引數,將保持原來的值。