Qt扫盲-QSqlQuery理论总结

一、概述

QSqlQuery类简而言之其实就是来执行SQL语言的工具类,QSqlQuery封装了在QSqlDatabase上执行的SQL查询中创建、导航和检索数据所涉及的功能。它可用于执行DML(数据操作语言)语句,如SELECT、INSERT、UPDATE和DELETE,以及DDL(数据定义语言)语句,如CREATE TABLE。它也可以用于执行非标准SQL的数据库特定命令(例如SET DATESTYLE=ISO for PostgreSQL)。也就是支持不同数据库的SQL特性。

成功执行的SQL语句将查询的状态设置为active,以便isActive()返回true。否则查询的状态将被设置为inactive。在任何一种情况下,当执行新的SQL语句时,查询都定位在无效记录上。在检索值之前,必须将活动查询导航到有效记录(以便isValid()返回true)。
对于某些数据库,如果在调用commit()或rollback()时存在一个活动查询(即SELECT语句),则提交或回滚将失败。也就是要在Select 执行完,提交回滚才会成功。详情请参见isActive()。

二、使用

1. 数据查询

导航主要是指在我们执行了查询后,我们应该会得到一个记录表,我们要在这个记录表里索引数据的时候就要用这个导航,导航记录的功能如下:

next()
previous()
first()
last()
seek()

这些函数允许我们向前、向后或任意地通过查询返回的记录。如果我们只需要通过结果向前移动(例如,通过使用next() ),您可以使用 setForwardOnly(),这将节省大量的内存开销,并提高某些数据库的性能。一旦活动查询定位到有效记录上,就可以使用value()检索数据。所有数据都是使用 QVariants 从SQL后端传输的,也就是每个字段的数据都是一个 QVariants 类型。

查询例子例子:

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

要访问查询返回的数据,请使用value(int)。SELECT语句返回的数据中的每个字段都是通过传递字段在语句中的位置来访问的,从0开始。这使得使用SELECT *查询是不可取的,因为返回字段的顺序是不确定的。
为了提高效率,没有通过名称访问字段的函数(除非您使用带名称的预准备查询,如下所述)。要将字段名转换为索引,请使用record().indexOf(),例如:

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

2.查询参数绑定

查询参数绑定其实就是在使用基本上所有的查询、删除、更新、插入数据的时候,得跟一些关键字,我们用参数化好像更安全些。

QSqlQuery 支持准备好的查询执行和将参数值绑定到占位符。有些数据库不支持这些特性,因此Qt模拟了所需的功能。例如,Oracle和ODBC驱动程序有适当的准备好的查询支持,Qt就用的现成的,但对于不支持此功能的数据库,Qt自己实现了该功能,例如在执行查询时用实际值替换占位符。使用numRowsAffected()来确定非SELECT查询影响了多少行,使用size()来确定SELECT查询检索了多少行。
Oracle数据库使用冒号-名称语法来标识占位符,例如 :name 。ODBC简单地使用 ? 字符。Qt同时支持这两种语法,但限制是不能在同一个查询中混合使用它们。我推荐就还是直接用ODBC连接就好啦。

我们还可以使用boundValues()检索单个变量(映射)中所有字段的值。使用如下

//方法一
QMapIterator<QString, QVariant> i(query.boundValues());
while (i.hasNext()) {
          i.next();
          cout << i.key().toUtf8().data() << ": "
               << i.value().toString().toUtf8().data() << Qt::endl;
}

//方法二
QList<QVariant> list = query.boundValues().values();
for (int i = 0; i < list.size(); ++i)
          cout << i << ": " << list.at(i).toString().toUtf8().data() << Qt::endl;

注意:并非所有SQL操作都支持绑定值。这个是每个数据库自己支不支持的问题,参考数据库系统的文档来检查它们是否可用。

3. 绑定值的方法

下面我们将分别使用四种不同的绑定方法给出相同的示例,以及一个将值绑定到存储过程的示例。(下面不仅仅局限于 Insert ,我们也可以用 Select、Update等等)

1. 使用命名占位符的命名绑定:

      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();

2. 使用命名占位符的位置绑定:

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();

3. 使用位置占位符绑定值(版本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();

4. 使用位置占位符绑定值(版本2):

QSqlQuery query;
query.prepare("INSERT INTO person (id, forename, surname) "
                    "VALUES (?, ?, ?)");
query.addBindValue(1001);
query.addBindValue("Bart");
query.addBindValue("Simpson");
query.exec();

5. 将值绑定到存储过程:

这段代码调用一个名为AsciiToInt()的存储过程,通过其in形参向其传递一个字符,并在out形参中获取其结果。

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

注意,未绑定的参数将保留它们的值。
警告:在创建QSqlQuery之前,必须加载SQL驱动程序并打开连接。此外,当查询存在时,连接必须保持打开状态;否则,QSqlQuery的行为是未定义的。

三、常见问题

很多问题会跟不同数据有关系,推荐最好使用官方的写法: QSqlError(“0“, “QODBC3: Unable to execute statement“, “[Microsoft][ODBC 驱动程序管理器] 函数序列错误“)

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Qt是一个跨平台的C++应用程序开发框架,它提供了丰富的功能和工具来简化应用程序的开发过程。在Qt中,可以使用QSqlQuery类来创建和操作数据库。 QSqlQuery类是Qt提供的用于执行SQL语句的类,它可以执行查询、插入、更新和删除等操作。下面是使用QSqlQuery类创建数据库的一般步骤: 1. 首先,需要在Qt项目中添加数据库模块的支持。可以在项目文件(.pro)中添加如下代码: ``` QT += sql ``` 2. 在代码中包含QSqlQuery头文件: ``` #include <QSqlQuery> ``` 3. 创建数据库连接: ``` QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("database.db"); // 设置数据库名称 if (!db.open()) { // 处理数据库连接失败的情况 } ``` 4. 执行SQL语句: ``` QSqlQuery query; query.exec("CREATE TABLE IF NOT EXISTS students (id INT PRIMARY KEY, name TEXT, age INT)"); ``` 上述代码创建了一个名为"students"的表,包含id、name和age三个字段。 5. 可以通过QSqlQuery的其他方法来执行不同的SQL操作,例如插入数据查询数据等。例如,插入一条数据: ``` query.prepare("INSERT INTO students (id, name, age) VALUES (:id, :name, :age)"); query.bindValue(":id", 1); query.bindValue(":name", "John"); query.bindValue(":age", 20); query.exec(); ``` 上述代码将一条id为1、name为"John"、age为20的记录插入到"students"表中。 6. 最后,记得在不需要使用数据库时关闭数据库连接: ``` db.close(); ``` 以上是使用QSqlQuery类创建数据库的基本步骤。你可以根据具体需求使用QSqlQuery的其他方法来执行更复杂的数据库操作

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

太阳风暴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值