执行SQL语句
1、执行一个查询
QSqlQuery类提供了一个接口,用于执行SQL语句和浏览查询的结果集。
要执行一个SQL语句,只需要简单地创建一个QSqlQuery 对象,然后调用QSqlQuery::exec()函数即可。
例如:
QSqlQuery query:
query.exec(“select * from student”);
在QSqlQuery的构造函数中可以接受一个可选的QSqlDatabase对象来指定使用哪一个数据库连接。 当没有指定连接时,就是默认连接。
如果发生了错误,那么exec()函数会返回false, 可以使用QSqlQuery::lastError()来获取错误信息。
2、浏览结果集
QsqlQuery 提供了对结果集的访问,可以一次访问一条记录。当执行完exec()函数后,QSqlQuery的内部指针会位于第一条记录前面的位置。必须调用一次QSqlQuery:next()函数来使其前进到第一条记录,然后可以重复使用next()函数来访问其他的记录,直到该函数的返回值为false。
遍历一个结果集:
while(query1.next())
{
qDebug() << query1.value(0).toInt() << query1.value(1).toString();
}
在QSqlquery类中提供了多个函数来实现在结果集中进行定位,比如:
next()定位到下一条记录。
previous 定位到前一条记录;
first () 定位到第一条记录;
seek()定位到第n条记录;
at()返回当前行的索引;
record()函数可以返回当前指向的记录里;
size()返回结果集中的总行数。
QSqlDriver::hasFeature() 数据库支持的特性。
项目示例:
#ifndef CONNECTION_H
#define CONNECTION_H
#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>
static bool createConnection()
{
// 创建一个数据库连接,使用“connection1”为连接名
QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE", "connection1");
db1.setDatabaseName("my1.db");
if (!db1.open()) {
QMessageBox::critical(0, "Cannot open database1",
"Unable to establish a database connection.", QMessageBox::Cancel);
return false;
}
// 这里要指定连接
QSqlQuery query1(db1);
query1.exec("create table student (id int primary key, "
"name varchar(20))");
query1.exec("insert into student values(0, 'LiMing')");
query1.exec("insert into student values(1, 'LiuTao')");
query1.exec("insert into student values(2, 'WangHong')");
// 创建另一个数据库连接,要使用不同的连接名,这里是“connection2”
QSqlDatabase db2 = QSqlDatabase::addDatabase("QSQLITE", "connection2");
db2.setDatabaseName("my2.db");
if (!db2.open()) {
QMessageBox::critical(0, "Cannot open database1",
"Unable to establish a database connection.", QMessageBox::Cancel);
return false;
}
// 这里要指定连接
QSqlQuery query2(db2);
query2.exec("create table student (id int primary key, "
"name varchar(20))");
query2.exec("insert into student values(10, 'LiQiang')");
query2.exec("insert into student values(11, 'MaLiang')");
query2.exec("insert into student values(12, 'ZhangBin')");
return true;
}
#endif // CONNECTION_H
#include <QApplication>
#include <QSqlDatabase>
#include <QDebug>
#include <QStringList>
#include "connection.h"
#include <QVariant>
#include <QSqlDriver>
#include <QSqlRecord>
#include <QSqlField>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 创建数据库连接
if (!createConnection()) return 1;
// 使用QSqlQuery查询连接1的整张表,先要使用连接名获取该连接
QSqlDatabase db1 = QSqlDatabase::database("connection1");
QSqlQuery query1(db1);
qDebug() << "connection1:";
query1.exec("select * from student");
while(query1.next())
{
qDebug() << query1.value(0).toInt() << query1.value(1).toString();
}
// 使用QSqlQuery查询连接2的整张表
QSqlDatabase db2 = QSqlDatabase::database("connection2");
QSqlQuery query2(db2);
qDebug() << "connection2:";
query2.exec("select * from student");
while(query2.next())
{
qDebug() << query2.value(0).toInt() << query2.value(1).toString();
}
// 以下是在例程17-4中添加的代码
int numRows;
// 先判断该数据库驱动是否支持QuerySize特性,如果支持,则可以使用size()函数,
// 如果不支持,那么就使用其他方法来获取总行数
if (db2.driver()->hasFeature(QSqlDriver::QuerySize)) {
qDebug() << "has feature: query size";
numRows = query2.size();
} else {
qDebug() << "no feature: query size";
query2.last();
numRows = query2.at() + 1;
}
qDebug() << "row number: " << numRows;
// 指向索引为1的记录,即第二条记录
query2.seek(1);
// 返回当前索引值
qDebug() << "current index: " << query2.at();
// 获取当前行的记录
QSqlRecord record = query2.record();
// 获取记录中“id”和“name”两个属性的值
int id = record.value("id").toInt();
QString name = record.value("name").toString();
qDebug() << "id: " << id << "name: " << name;
// 获取索引为1的属性,即第二个属性
QSqlField field = record.field(1);
// 输出属性名和属性值,结果为“name”和“MaLiang”
qDebug() << "second field: " << field.name()
<< "field value: " << field.value().toString();
return a.exec();
}
3、插入、更新和删除记录
插入一条记录:
query2.exec(“insert into student (id, name) values (100, chenyun)”);
插入多条记录:
// 下面是与上面代码等价的名称绑定实现代码
// query2.prepare("insert into student (id, name) values (:id, :name)");
// int idValue = 100;
// QString nameValue = "ChenYun";
// query2.bindValue(":id", idValue);
// query2.bindValue(":name", nameValue);
// query2.exec();
// 下面是与上面代码等价的位置绑定实现代码
// query2.prepare("insert into student (id, name) values (?, ?)");
// int idValue = 100;
// QString nameValue = "ChenYun";
// query2.addBindValue(idValue);
// query2.addBindValue(nameValue);
// query2.exec();
// 批处理
query2.prepare("insert into student (id, name) values (?, ?)");
QVariantList ids;
ids << 20 << 21 << 22;
query2.addBindValue(ids);
QVariantList names;
names << "xiaoming" << "xiaoliang" << "xiaogang";
query2.addBindValue(names);
if(!query2.execBatch()) qDebug() << query2.lastError();
对于记录的更新和删除,它们和插入操作是相似的,并且也可以使用占位符。
**// 更新**
query2.exec("update student set name = 'xiaohong' where id = 20");
**// 删除**
query2.exec("delete from student where id = 21");
query2.exec("select * from student");
while(query2.next())
{
qDebug() << query2.value(0).toInt() << query2.value(1).toString();
}
4、事务
事务可以保证一个复杂操作的原子性。就是对于一个数据库的操作序列,这些操作要么全部做完,要么一条也不做,它是一个不可分割的工作单位。
在Qt中,如果底层的数据库引擎支持事务,那么
QSqlDatabase::hasFeature(QSqlDriver::Transactions)会返回true。
可以使用QSqlDatabase::transaction()来启动一个事务,
然后编写一些希望在事务中执行的SQL语句,
最后调用QSqlDatabase::commit()或者QSqlDatabase::rollback()。
当使用事务时必须在创建查询以前就开始事务,例如:
QSqlDatabase::database().transaction();
QSqlQuery query3;
query3.exec(“SELECT ID FROM employee WHERE name = Torid Halvorsen”);
if(query3.next())
{
int employeeId = query3.value(0).toInt();
query3.exec(“INSERT INTO project(id,name,ownerid)” “VALUES(201,Manhattan Project,”+ QString::number(employeeId)+"")");
}
QSqlDatabase::database().commit();
本文档整理来源自《QtCreator 快速入门》。。。。