QT数据库操作QSqlQuery

时间:2021-04-13 10:45:40

数据库对大多数应用来说,大概是必备吧。如何对数据库进行增删改查等操作也许就是关键了。在QT中如何对数据库进行这些操作呢?QSqlQuery类可以完成!如何使用它呢?看下面吧!(对数据库操作前需要先连接数据库,连接数据库请先查看数据库连接


QSqlQuery

QSqlQuery支持DML(data manipulation language)语法,如:SELECT,
INSERT,UPDATE and DELETE
;也支持DDL(data definition language)语法,如:CREATE TABLE;还支持非标准的特点数据库命令,如:SET DATESTYLE=ISO for PostgreSQL。
注意:在QSqlQuery对象创建前,打开数据库,且保持其打开状态,否则将出现未定义行为。

执行操作

bool QSqlQuery::exec()
bool QSqlQuery::exec(const QString & query)

执行数据库操作,将重置lastError(),并将使isActive()返回true,直到其完成操作。
第一个函数使用前序使用bool QSqlQuery::prepare(const QString & query)准备操作语句,第二个函数则直接使用操作语句。

//方式一:
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();

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

注意:

  • 当QSQLDatabase使用了连接名,即如addDatabase("QMYSQL","connName")时,需使用构造函数QSqlQuery(QSqlDatabase db)
  • 一些数据库会延迟prepare()直到调用exec(),这将导致不能正确执行。
  • 在SQLite中,同时执行超过一条语句将导致函数返回false。

结束操作

void QSqlQuery::finish()

该函数通常无需调用,除非同一QSqlQuery对象间隔一段时间再使用时,调用该函数可释放资源。调用该函数将使isActive()返回false

状态查询

bool QSqlQuery::isActive() const

当QSqlQuery对象成功exec(),且未结束时,返回true。
注意:正在活动SELECT查询,将导致commit()rollback()失败。

操作查询记录

bool QSqlQuery::next()
bool QSqlQuery::previous()
bool QSqlQuery::first()
bool QSqlQuery::last()
bool QSqlQuery::seek(int index, bool relative = false)

只向前取数据

void QSqlQuery::setForwardOnly(bool forward)

当forward为true时,只有next()seek()操作可用,且可以减少缓存的使用,还可以提高某些数据库的性能。在QSqlQuery对象执行后设置将导致结果未定义,或崩溃。

读取获得的数据

QVariant QSqlQuery::value(int index) const

例:

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

注意:SELECT * FROM table的字符返回是不确定的,不宜使用value(0)等。可使用record().indexOf()将字段名转换为索引值。

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

执行效果

int QSqlQuery::numRowsAffected() const

当non-SELECT时,使用上面的函数,当SELECT时,需使用下面的函数

int QSqlQuery::size() const

使用isSelect()判断是否为SELECT语句。

绑定占位符变量

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

Qt支持的绑定方式

  • 名称绑定到名称占位符

    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();
  • 位置绑定到名称占位符

    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();
  • 绑定值到位置占位符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();
  • 绑定值到位置占位符2

    QSqlQuery query;
    query.prepare("INSERT INTO person (id, forename, surname) "
    "VALUES (?, ?, ?)");
    query.addBindValue(1001);
    query.addBindValue("Bart");
    query.addBindValue("Simpson");
    query.exec();
  • 绑定值到存储器(不完全支持)

    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

    注意:未绑定的参数,将保持原来的值。