1. 程式人生 > >Qt資料庫:(三)利用QSqlQuery類執行SQL語句(一)

Qt資料庫:(三)利用QSqlQuery類執行SQL語句(一)

SQL即結構化查詢語言,是關係資料庫的標準語言。前面已經提到,在Qt中利用QSqlQuery類實現了執行SQL語句。需要說明,我們這裡只是Qt教程,而非專業的資料庫教程,所以我們不會對資料庫中的一些知識進行深入講解,下面只是對最常用的幾個知識點進行講解。

我們下面先建立一個工程,然後講解四個知識點,分別是:

一,操作SQL語句返回的結果集。

二,在SQL語句中使用變數。

三,批處理操作。

四,事務操作。

我們新建Qt4 Gui Application工程,我這裡工程名為data2,然後選中QtSql模組,Base class選QWidget。工程建好後,新增C++ Header File ,命名為connection.h ,更改其內容如下:

#ifndefCONNECTION_H
#defineCONNECTION_H
#include<QMessageBox>
#include<QSqlDatabase>
#include<QSqlQuery>
#include<QtDebug>
#include<QtGui>
#include<qdebug.h>
staticboolcreatConnection()
{
QSqlDatabasedb=QSqlDatabase::addDatabase("QSQLITE");//新增資料庫驅動
db.setDatabaseName(":memory:"
);//資料庫連線命名
if(!db.open())//開啟資料庫
{
qDebug("openisfalse");
returnfalse;
}
else
{
qDebug("openisOK");
}
QSqlQueryquery(db);//以下執行相關QSL語句
boolbuscess=query.exec("createtableperson(idintprimarykey,firstnamevarchar(20),lastnamevarchar(20))");
//新建person表,id設定為主鍵,一個firstname項,還有一個lastname項
query.exec("insertintopersonvalues(101,
'Danny','Young')");
query.exec("insertintopersonvalues(102,'Christine','Holand')");
query.exec("insertintopersonvalues(103,'Lars','Gordon')");
query.exec("insertintopersonvalues(104,'Roberto','Robitaille')");
query.exec("insertintopersonvalues(105,'Maria','Papadopoulos')");
//向表中插入5條記錄
if(!buscess)
{
qDebug("tableiserror");
}
else
{
qDebug("tableissucess");
}
returntrue;
}
#endif//CONNECTION_H

然後更改main.cpp的內容如下:

#include<QtGui/QApplication>
#include"widget.h"
#include"connection.h"
#include<QtSql>
#include<QtDebug>
#include<qdebug.h>
#include<QSqlQuery>
intmain(intargc,char*argv[])
{
QApplicationa(argc,argv);
if(!creatConnection())
return1;
Widgetw;
w.show();
returna.exec();
}

可以看到,我們是在主函式中開啟資料庫的,而資料庫連線用一個函式完成,並單獨放在一個檔案中,這樣的做法使得主函式很簡潔。我們今後使用資料庫時均使用這種方法。我們開啟資料庫連線後,新建了一個人員表,並在其中插入了幾條記錄。

101 "Danny""Young"

102 "Christine" "Holand"

103 "Lars""Gordon"

104 "Roberto""Robitaille"

105 "Maria""Papadopoulos" 

表中的一行就叫做一條記錄,一列是一個屬性。這個表共有5條記錄,id、firstname和lastname三個屬性。程式中的“id int primary key”表明id屬性是主鍵,也就是說以後新增記錄時,必須有id項。

下面我們開啟widget.ui檔案,在設計器中向介面上新增一個Push Button ,和一個Spin Box 。將按鈕的文字改為“查詢”,然後進入其單擊事件槽函式,更改如下。

voidWidget::on_pushButton_clicked()
{
QSqlQueryquery;
query.exec("select*fromperson");
while(query.next())
{
qDebug()<<query.value(0).toInt()<<query.value(1).toString()<<query.value(2).toString();
}
}

我們在widget.cpp中新增標頭檔案:

#include <QSqlQuery>#include <QtDebug>

然後執行程式,單擊“查詢”按鈕,效果如下:

可以看到在輸出視窗,表中的所有內容都輸出出來了。這表明我們的資料庫連線已經成功建立了。

一,操作SQL語句返回的結果集。

在上面的程式中,我們使用query.exec(“select * from person”);來查詢出表中所有的內容。其中的SQL語句“select * from person”中“*”號表明查詢表中記錄的所有屬性。而當query.exec(“select * from person”);這條語句執行完後,我們便獲得了相應的執行結果,因為獲得的結果可能不止一條記錄,所以我們稱之為結果集。

結果集其實就是查詢到的所有記錄的集合,而在QSqlQuery類中提供了多個函式來操作這個集合,需要注意這個集合中的記錄是從0開始編號的。最常用的有:

seek(int n) :query指向結果集的第n條記錄。

first() :query指向結果集的第一條記錄。

last() :query指向結果集的最後一條記錄。

next() :query指向下一條記錄,每執行一次該函式,便指向相鄰的下一條記錄。

previous() :query指向上一條記錄,每執行一次該函式,便指向相鄰的上一條記錄。

record() :獲得現在指向的記錄。

value(int n) :獲得屬性的值。其中n表示你查詢的第n個屬性,比方上面我們使用“select * from person”就相當於“select id, firstname,lastname from person”,那麼value(0)返回id屬性的值,value(1)返回firstname屬性的值,value(2)返回lastname屬性的值。該函式返回QVariant型別的資料,關於該型別與其他型別的對應關係,可以在幫助中檢視QVariant。

at() :獲得現在query指向的記錄在結果集中的編號。

需要說明,當剛執行完query.exec(“select * from person”);這行程式碼時,query是指向結果集以外的,我們可以利用query.next(),當第一次執行這句程式碼時,query便指向了結果集的第一條記錄。當然我們也可以利用seek(0)函式或者first()函式使query指向結果集的第一條記錄。但是為了節省記憶體開銷,推薦的方法是,在query.exec(“select * from person”);這行程式碼前加上query.setForwardOnly(true);這條程式碼,此後只能使用next()和seek()函式。

下面將“查詢”按鈕的槽函式更改如下:

voidWidget::on_pushButton_clicked()
{
QSqlQueryquery;
query.exec("select*fromperson");
//while(query.next())
//{
//qDebug()<<query.value(0).toInt()<<query.value(1).toString()<<query.value(2).toString();
//}
qDebug()<<"execnext()";
if(query.next())
//開始就先執行一次next()函式,那麼query指向結果集的第一條記錄
{
introwNum=query.at();
//獲取query所指向的記錄在結果集中的編號
intcolumnNum=query.record().count();
//獲取每條記錄中屬性(即列)的個數
intfieldNo1=query.record().indexOf("firstname");
//獲取firstname屬性所在列的編號,列從左向右編號,最左邊的編號為0
intfieldNo2=query.record().indexOf("lastname");
//獲取lastname屬性所在列的編號,列從左向右編號,最左邊的編號為0
intid=query.value(0).toInt();
//獲取id屬性的值,並轉換為int型
QStringfirstname=query.value(1).toString();
//獲取firstname屬性的值
QStringlastname=query.value(2).toString();
//獲取lastname屬性的值
qDebug()<<"rowNumis:"<<rowNum//將結果輸出
<<"columnNumis:"<<columnNum
<<"fieldNo1is:"<<fieldNo1
<<"fieldNo2is:"<<fieldNo2
<<"idis:"<<id
<<"firstnameis:"<<firstname
<<"lastnameis:"<<lastname;
}
qDebug()<<"execseek(2):";
if(query.seek(2))
//定位到結果集中編號為2的記錄,即第三條記錄,因為第一條記錄的編號為0
{
qDebug()<<"rowNumis:"<<query.at()
<<"idis:"<<query.value(0).toInt()
<<"firstnameis:"<<query.value(1).toString()
<<"lastnameis:"<<query.value(2).toString();
}
qDebug()<<"execlast():";
if(query.last())
//定位到結果集中最後一條記錄
{
qDebug()<<"rowNumis:"<<query.at()
<<"idis:"<<query.value(0).toInt()
<<"firstnameis:"<<query.value(1).toString()
<<"lastnameis:"<<query.value(2).toString();
}
}

然後在widget.cpp檔案中新增標頭檔案。

#include <QSqlRecord>

執行程式,結果如下: