Qt SQL:QSqlQuery

一、描述

QSqlQuery 类提供了一种执行和操作 SQL 语句的方法。

QSqlQuery 封装了在 QSqlDatabase 上执行的 SQL 查询中创建、导航和检索数据所涉及的功能。它可用于执行 DML(数据操作语言)语句,如 SELECTINSERTUPDATEDELETE,以及 DDL(数据定义语言)语句,如 CREATE TABLE。它还可用于执行非标准 SQL 的特定于数据库的命令。

成功执行的 SQL 语句将查询的状态设置为活动(isActive() 返回 true)。

使用以下功能执行导航记录:

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

这些函数可以在查询返回的记录中向前、向后或任意移动。如果只需要在结果中前进移到,可以使用 setForwardOnly(),这将节省大量内存开销并提高某些数据库的性能。如:

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

使用 value(int) 访问查询返回的数据(从 0 开始)。SELECT 语句返回的数据中的字段是通过传递该字段在语句中的位置来访问的。

必须在创建 QSqlQuery 之前加载 SQL 驱动程序并打开连接。此外,查询存在时连接必须保持打开状态,否则 QSqlQuery 的行为是未定义的。

1.1、绑定值

QSqlQuery 支持将参数值绑定到占位符。

下面展示了使用几种不同绑定方法将值绑定到存储过程的示例。

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

二、类型成员

1、enum QSqlQuery::BatchExecutionMode

  • ValuesAsRows:更新多行。将 QVariantList 中的每个条目视为更新下一行的值。
  • ValuesAsColumns:更新单行。将 QVariantList 中的每个条目视为数组类型的单个值。

三、成员函数

1、void addBindValue(const QVariant &val, QSql::ParamType paramType = QSql::In)

将值 val 添加到绑定值列表中。

使用无效的 QVarian绑定 NULL 值。

enum QSql::ParamTypeFlag:此枚举用于指定绑定参数的类型。

  • QSql::In:绑定参数用于将数据放入数据库。
  • QSql::Out:绑定参数用于从数据库接收数据。
  • QSql::InOut:绑定参数用于将数据放入数据库,它将在执行查询时被输出数据覆盖。
  • QSql::Binary:如果想指示正在传输的数据是原始二进制数据,则必须与其他标志进行或运算。

2、int at()

返回查询的当前内部位置。第一条记录位于零位置。

如果位置无效,函数返回 QSql::BeforeFirstRowQSql::AfterLastRow

enum QSql::Location:此枚举类型描述了特殊的 SQL 导航位置:

  • QSql::BeforeFirstRow::在第一条记录之前。
  • QSql::AfterLastRow:最后一条记录之后。

3、void bindValue(const QString &placeholder, const QVariant &val, QSql::ParamType paramType = QSql::In)

将占位符 placeholder 设置为绑定到准备好的语句中的值 val。

在指定占位符名称时必须包含占位符标记(例如)。

      void bindValue(int pos, const QVariant &val, QSql::ParamType paramType = QSql::In)

将位置 pos 的占位符设置为绑定到准备好的语句中的值 val。

4、QVariant boundValue(const QString &placeholder)

返回占位符的值。

      QVariant boundValue(int pos)

返回位置 pos 的占位符的值。

5、QVariantList boundValues()

返回绑定值的列表。列表的顺序是绑定顺序,不管是使用命名绑定还是位置绑定。

    QVariantList list = query.boundValues();
    for (int i = 0; i < list.size(); ++i)
        cout << i << ": " << list.at(i).toString().toUtf8().data() << "\n";

6、void clear()

清除结果集并释放查询对象持有的所有资源。将查询状态设置为非活动。

7、const QSqlDriver * driver()

返回与查询对象关联的数据库驱动程序。

8、bool exec(const QString &query)

执行 query 中的 SQL语句。如果执行成功,则返回 true 并将查询状态设置为活动,否则返回false。

参数字符串必须使用适合被查询的 SQL 数据库的语法。

执行后,查询对象定位在无效记录上,必须先导航到有效记录,然后才能检索数据值(如使用 next())。

调用 exec() 时会重置此查询对象的最后一个错误。

对于 SQLite,query 字符串一次只能包含一条语句。如果给出了多个语句,则返回 false。

//执行SQL语句
std::tuple DBUtil::executeSql(const QString & sqlCommand)
{
    db.transaction();
    QSqlQuery query(db);
    bool executeResult = query.exec(sqlCommand);
    db.commit();
    QSqlError err = query.lastError();
    std::tuple tuple(executeResult,err,query);
    return tuple;
}

      bool exec()

执行先前准备好的 SQL 语句。返回执行是否成功。

9、bool execBatch(QSqlQuery::BatchExecutionMode mode = ValuesAsRows)

批量执行之前准备好的 SQL 语句。返回执行是否成功。

    QSqlQuery q;
    q.prepare("insert into myTable values (?, ?)");

    QVariantList ints;
    ints << 1 << 2 << 3 << 4;
    q.addBindValue(ints);

    QVariantList names;
    names << "Harald" << "Boris" << "Trond" << QVariant(QMetaType::QString);
    q.addBindValue(names);

    if (!q.execBatch())
        qDebug() << q.lastError();

上面的示例插入了四个新行:

1 Harald

2 Boris

3 Trond

4 NULL

列表中 QVariants 的类型不得更改。如不能在 QVariantList 中混合整数和字符串 QVariants

10、QString executedQuery()

返回成功执行的最后一个 SQL 字符串。

11、QString lastQuery()

返回正在使用的当前 SQL 文本。

Qt SQL:QSqlQuery_第1张图片

12、void finish()

将查询对象设置为非活动状态,指示数据库驱动程序在重新执行之前不会从此查询对象中获取更多数据。

通常不需要调用此函数,但如果之后要重新使用查询对象,此函数可用于释放锁或游标等资源。

Qt SQL:QSqlQuery_第2张图片

13、bool first()

检索结果中的第一条记录(如果可用),并将查询定位在检索到的记录上。

如果不成功,则将查询位置设置为无效位置并返回 false。

Qt SQL:QSqlQuery_第3张图片

14、bool isActive()

查询对象是否处于活动状态。活动的 QSqlQuery 是一个已经成功执行但尚未 finish() 的 QSqlQuery。

可以通过调用 finish() 或 clear() 使查询对象不活动。

15、bool isForwardOnly()

是否只能向前滚动结果集。

16、bool isNull(int field)

如果查询未激活、查询未定位在有效记录上、没有 field 字段或该字段内容为空,则返回 true。

Qt SQL:QSqlQuery_第4张图片

      bool isNull(const QString &name)

Qt SQL:QSqlQuery_第5张图片

17、bool isSelect()

当前查询是否 SELECT 语句。

18、bool isValid()

查询对象当前是否位于有效记录上。

19、bool last()

检索结果中的最后一条记录(如果可用),并将查询定位在检索到的记录上。

如果不成功,则将查询位置设置为无效位置并返回 false。

Qt SQL:QSqlQuery_第6张图片

20、QSqlError lastError()

返回有关此查询发生的最后一个错误(如果有)的错误信息。

21、QVariant lastInsertId()

如果数据库支持,则返回最近插入行的对象 ID。如果插入操作多于一行,则行为未定义。

22、bool next()

检索结果中的下一条记录(如果可用),并将查询定位在检索到的记录上。

Qt SQL:QSqlQuery_第7张图片

23、bool nextResult()

丢弃当前结果集并导航到下一个结果(如果可用)。

一些数据库能够为存储过程或 SQL 批处理(包含多个语句的查询字符串)返回多个结果集。如果执行查询后有多个结果集可用,则此函数可用于导航到下一个结果集。

  • 如果有新的结果集可用,此函数将返回 true。查询将重新定位在新结果集中的无效记录上,并且必须先导航到有效记录,然后才能检索数据值。
  • 如果新的结果集不可用,该函数将返回 false 并将查询对象设置为非活动状态。

24、int numRowsAffected()

返回受 SQL 语句查询结果影响的行数,如果无法确定,则返回 -1。

对于 SELECT 语句,该函数返回值是未定义的应改用 size() 。

如果查询未激活,则返回 -1。

25、bool prepare(const QString &query)

配置 SQL 语句查询以供执行。

Qt SQL:QSqlQuery_第8张图片

对于 SQLite,一次只能包含一条语句。如果给出了多个语句,则该函数返回 false。

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

26、bool previous()

检索结果中的前一条记录(如果可用),并将查询定位在检索到的记录上。 

Qt SQL:QSqlQuery_第9张图片

27、QSqlRecord record()

返回包含当前查询的字段信息的 QSqlRecord。

要从查询中检索值,应该使用 value(),因为它基于索引的查找速度更快。

在以下示例中,将执行 SELECT * FROM 查询。由于 SELECT 返回的列的顺序可能是随机的,因此使用 QSqlRecord::indexOf() 来获取列的索引。

QSqlQuery q("select * from employees");
QSqlRecord rec = q.record();

qDebug() << "Number of columns: " << rec.count();

int nameCol = rec.indexOf("name"); // index of the field "name"
while (q.next())
    qDebug() << q.value(nameCol).toString();

28、const QSqlResult * result()

返回与查询关联的结果。

29、bool seek(int index, bool relative = false)

检索位置 index 处的记录(如果可用),并将查询对象定位在检索到的记录上。第一条记录位于位置 0。

30、void setForwardOnly(bool forward)

设置是否仅向前模式。默认为关闭。

如果 forward 为 true,则仅允许具有正值的 next() 和 seek() 导航结果。

此模式可以(取决于驱动程序)更节省内存,因为不需要缓存结果。

此设置是对数据库引擎的建议。isForwardOnly() 将始终返回结果集的正确状态。

31、void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)

设置查询使用的数值精度策略。

不支持获取低精度数值的驱动程序将忽略精度策略。可以使用 QSqlDriver::hasFeature() 来确定驱动程序是否支持此功能。

32、int size()

返回结果的数目,如果无法确定数目或数据库不支持报告有关查询结果的数目的信息,则返回 -1。

对于非 SELECT 语句(isSelect() 返回 false),size() 将返回 -1。

对于 SELECT 语句应使用 numRowsAffected()。

Qt SQL:QSqlQuery_第10张图片

33、QVariant value(int index)

返回当前记录中字段索引的值。

Qt SQL:QSqlQuery_第11张图片

字段使用 SELECT 语句的文本从左到右编号,如:

SELECT forename, surname FROM people;

字段 0 是 forename,字段 1 是 surname。

不建议使用 SELECT *,因为查询中字段的顺序未定义。

      QVariant value(const QString &name)

返回当前记录中名为 name 的字段的值。

Qt SQL:QSqlQuery_第12张图片

你可能感兴趣的:(Qt,SQL,qt,sql)