QSqlQuery类提供了一个用于执行SQL语句和浏览查询的结果集的接口。

  QSqlQueryModel和QSqlTableModel类提供了一个用于访问数据库的高级接口,这将在下一节介绍。如果你不熟悉SQL,你可以直接使用下一节介绍的高级接口类。

1 执行一个查询

  要执行一个SQL语句,简单的创建一个QSqlQuery对象,然后调用QSqlQuery::exec()方法即可,如下所示:

QSqlQuery query;
query.exec("SELECT name, salary FROM employee WHERE salary > 50000");

  QSqlQuery的构造函数接受一个可选的QSqlDatabase对象参数,用来指定将使用哪一个数据库连接。在上面的例子中,我们并没有指定任何连接,因此使用默认连接。如果执行查询时出错,exec()将返回false,错误原因可以通过QSqlQuery::lastError()查看。

2 浏览查询结果

  QSqlQuery提供了一个访问一条查询结果记录的方法。在调用了exec()方法之后,QSqlQuery的内部指针定位到了第一条记录之前的位置。我们必须调用一次QSqlQuery::next()内部指针就移动到第一条记录上,然后重复调用next()方法就可以移动到其他记录上,直到该函数返回false为止。下面给出一个典型的循环依次遍历所有的记录:

while (query.next()) {
QString name = query.value().toString();
int salary = query.value().toInt();
qDebug() << name << salary;
}

  QSqlQuery::value()函数返回当前记录的一个字段值。字段的索引号从0开始计数。QSqlQuery::value()返回一个QVariant,这个类型可以保存各种C++和核心的Qt数据类型,比如int, QString和QByteArray等。不同的数据库类型将自动地映射到最近的Qt等价类型。在上面的代码中,我们使用了QVariant::toString()和QVariant::toInt()将变量类型转换为了QString和int。

补充:关于value()方法的参数-索引号的取值范围问题,我们只知道第一个字段对应的索引号为0,但是并不知道最后一个字段的索引号的时候,我们可以遍历所有可能值,由于当value()函数的索引号非法时,会返回一个非法的QVariant变量,因此,我们可以通过判断返回的QVariant变量的合法性来得知是否已经到了最后一个字段。下面给出一段示例代码:

while (query.next()){
int i = ;
QString result;
QVariant temp;
while ((temp = query.value(i++)).isValid()){
result += temp.toString();
result += " | ";
}
ui->textBrowser->append(result);
}

下面给出一个MYSQL与Qt支持的数据类型之间的转换关系表:

SQLITE3与Qt支持的数据类型之间的转换关系表如下:

  你可以使用QSqlQuery::next(),QSqlQuery::previous(), QSqlQuery::first()和QSqlQuery::last()来前后移动指向记录位置的指针。可以使用QSqlQuery::at()返回当前行的索引号,如果对应的数据库支持,可以使用QSqlQuery::size()返回查询结果集的总的行数(MYSQL是支持的)。

  要验证一个数据库驱动是否支持某一个特性,QSqlDriver::hasFeature()。下面的示例我们调用调用QSqlQuery::size()来检查底层的数据库是否支持此特性,否则,我们只能浏览到最后一条记录,利用查询的位置来得到查询结果中一共有多少条记录。

QSqlQuery query;
int numRows;
query.exec("SELECT name, salary FROM employee WHERE salary > 50000"); QSqlDatabase defaultDB = QSqlDatabase::database();
if (defaultDB.driver()->hasFeature(QSqlDriver::QuerySize)) {
numRows = query.size();
} else {
// this can be very slow
query.last();
numRows = query.at() + ;
}

  如果你在遍历查询结果集的时候只使用正值参数的next()和seek(),你可以在调用exec()之前调用QSqlQuery::setForwartOnly(true)。当你在操作大量结果集的时候,这是一个简单的优化单可以明显加速你的查询。

3 插入、更新和删除记录

  QSqlQuery可以执行任意的SQL语句。下面的示例展示了使用INSERT语句向表中插入一条记录:

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

  如果你想要同时插入许多条记录,一个有效的方法就是将查询语句和真实的值分离,这个可以使用占位符来实现。Qt支持两种占位符:名称绑定和位置绑定。下面是一个名称绑定的示例:

QSqlQuery query;
query.prepare("INSERT INTO employee (id, name, salary) "
"VALUES (:id, :name, :salary)");
query.bindValue(":id", );
query.bindValue(":name", "Thad Beaumont");
query.bindValue(":salary", );
query.exec();

  下面的代码时位置绑定的示例:

QSqlQuery query;
query.prepare("INSERT INTO employee (id, name, salary) "
"VALUES (?, ?, ?)");
query.addBindValue();
query.addBindValue("Thad Beaumont");
query.addBindValue();
query.exec();

  这两种语句对于Qt提供的所有数据库驱动都支持。当需要插入多条记录时,只需要调用 一次QSqlQuery::prepare(),然后使用多次bindValue()或者addBindValue()来绑定需要的数据,最后再调用一次exec()函数就可以了。

  抛开性能,使用占位符的一个好处就是你可以指定任意的值而不用担心缺少特殊字符。

  更新一条记录与插入操作非常相似:

QSqlQuery query;
query.exec("UPDATE employee SET salary = 70000 WHERE id = 1003");

  你也可以使用名称或位置绑定来关联实际的参数值。

  最后,下面给出一条删除语句:

QSqlQuery query;
query.exec("DELETE FROM employee WHERE id = 1007");

4 事务

  如果底层的数据库引擎支持事务,那么QSqlDriver::hasFeature(QSqlDriver::Transactions)会返回true。可以使用QSqlDatabase::transaction()启动一个事务,然后编写一些希望在事务中执行的SQL语句,最后调用QSqlDatabase::commit()或者QSqlDatabase::rollback()。当使用事务时必须在创建查询以前就开始事务,例如:

QSqlDatabase::database().transaction();
QSqlQuery query;
query.exec("SELECT id FROM employee WHERE name = 'Torild Halvorsen'");
if (query.next()) {
int employeeId = query.value().toInt();
query.exec("INSERT INTO project (id, name, ownerid) "
"VALUES (201, 'Manhattan Project', "
+ QString::number(employeeId) + ')');
}
QSqlDatabase::database().commit();

  事务可以保证一个复杂操作的原子性,就是对于一个数据库操作序列,这些操作要么全部做完,要么一条也不做,它是一个不可分割的工作单位。

QtSQL学习笔记(3)- 执行SQL语句的更多相关文章

  1. SQL学习笔记:基础SQL语句

    目录 语句特点 进入数据库 基本查询语句 SELECT DISTINCT WHERE AND/OR/NOT :逻辑运算符 ORDER BY :排序 基本修改语句 INSERT:添加语句 UPDATE: ...

  2. Ibatis学习总结7--SqlMapClient 执行 SQL 语句

    SqlMapCient 类提供了执行所有 mapped statement 的 API.这些方法如下: public int insert(String statementName, Object p ...

  3. CUBRID学习笔记 28 执行sql脚本文件

    一下命令在csql下执行. insert_commands.sql为sql脚本文件 ;CL ;READ insert_commands.sql ;RU 第一行的cl 清空命令缓存,等同clear第二行 ...

  4. 吴裕雄--天生自然ORACLE数据库学习笔记:优化SQL语句

    create or replace procedure trun_table(table_deleted in varchar2) as --创建一个存储过程,传入一个表示表名称的参数,实现清空指定的 ...

  5. 10.1(java学习笔记)JDBC基本操作(连接,执行SQL语句,获取结果集)

    一.JDBC JDBC的全称是java database connection java数据库连接. 在java中需要对数据库进行一系列的操作,这时就需要使用JDBC. sun公司制定了关于数据库操作 ...

  6. SQL反模式学习笔记18 减少SQL查询数据,避免使用一条SQL语句解决复杂问题

    目标:减少SQL查询数据,避免使用一条SQL语句解决复杂问题 反模式:视图使用一步操作,单个SQL语句解决复杂问题 使用一个查询来获得所有结果的最常见后果就是产生了一个笛卡尔积.导致查询性能降低. 如 ...

  7. MyBatis学习 之 二、SQL语句映射文件(2)增删改查、参数、缓存

    目录(?)[-] 二SQL语句映射文件2增删改查参数缓存 select insert updatedelete sql parameters 基本类型参数 Java实体类型参数 Map参数 多参数的实 ...

  8. MyBatis学习 之 二、SQL语句映射文件(1)resultMap

    目录(?)[-] 二SQL语句映射文件1resultMap resultMap idresult constructor association联合 使用select实现联合 使用resultMap实 ...

  9. SQL*PLUS中批量执行SQL语句

    SQL*PLUS中批量执行SQL语句 今天由于工作的需要,要在CMD中批量执行大量的SQL语句,对于Oracle学习还处在入门阶段的我,只能硬着头皮到处去寻找资料(主要是网络资料,也包括自己的电子书) ...

随机推荐

  1. BZOJ 1090: [SCOI2003]字符串折叠 区间DP

    1090: [SCOI2003]字符串折叠 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...

  2. delphi 窗体透明

        TransparentColor:=true;    TransparentColorValue:=clFuchsia;    Color:= TransparentColorValue;  ...

  3. 关于unity3d播放flash动画,使用插件uniswf

    主要就是代码了. 1.using UnityEngine; using System.Collections; using pumpkin.swf; using System.Collections. ...

  4. STL——迭代器的概念

    迭代器是一种抽象的设计概念,现实程序语言中并没有直接对应于这个概念的实物. 1 迭代器设计思维——STL关键所在 不论是泛型思维或STL的实际运用,迭代器都扮演这重要的角色.STL的中心思想在于:将数 ...

  5. Input

    Input Basic Input Old Input Files Please note that both Input and Request do NOT sanitize your data, ...

  6. Forms and actions

    Forms and actions Adding new albums We can now code up the functionality to add new albums. There ar ...

  7. Spring3之JDBC

    Spring提供了统一的数据访问异常层次体系,所涉及到的大部分异常类型都定义在org.springframework.dao包中,出于这个体系中所有异常类型均以org.springframework. ...

  8. c++ (P10—46)

    1 signed unsigned short long 四个修饰符.对int全部适用,对char只有signed和unsigned适用,long适用于double. 2 long int(占4个字节 ...

  9. linux中shell编程

    shell编程 1 echo -e 识别\转义符 \a \b \t \n \x十六进制 \0八进制 等等 #!/bin/bash echo -e "hello world" 执行脚 ...

  10. matlab——sparse函数和full函数(稀疏矩阵和非稀疏矩阵转换)

    函数功能:生成稀疏矩阵 使用方法 :S = sparse(A) 将矩阵A转化为稀疏矩阵形式,即矩阵A中任何0元素被去除,非零元素及其下标组成矩阵S.如果A本身是稀疏的,sparse(S)返回S. S ...