QSqlQuery类提供咯一种执行和操作SQL 语句的手段。
QSqlQuery将那些与在某个 QSqlDatabase 上执行的SQL 查询有关的创建、遍历和获取数据的功能封装起来。它可以用来执行:DML (数据操作语言)语句,例如 SELECT 、 INSERT 、 UPDATE 和 DELETE ;以及DDL (数据定义语言)语句,例如 CREATE TABLE 。它还可以用来执行那些并非标准SQL 的与特定数据库相关的命令(例如,对于PostgreSQL,可执行 DATESTYLE=ISO )。
当SQL 语句被成功执行时,会将查询的状态设置成活动的(active),那样的话, isActive ()返回真。否则的话,查询的状态就被设置成非活动的(inactive)。在这两种情况下,每当正在执行一个新的SQL 语句时,查询都会被放置于一个无效的记录处。在从一个活动的查询中获取数据之前,必须将它遍历到一个有效的记录(使 isValid ()返回真)。
对于某些数据库,如果在你调用 commit() 或 rollback() 时有一个对应于 SELECT 语句的活动查询存在的话,那么这次提交(commit)或回滚(rollback)会失败。查看 isActive ()以了解详细信息。
• next ()
• previous ()
• first ()
• last ()
• seek ()
这些函数允许程序猿在查询返回的记录中向前、向后或者任意地移动。如果你只需要在结果中向前移动(例如,使用 next ())的话,那么你可以使用 setForwardOnly (),它会显著地节约一部分内存开销,并且在某些数据库中提升性能。一旦某个活动的查询被放置在一个有效的记录上时,就可以使用 value ()来获取数据。所有的数据都是使用 QVariants 从SQL 后端传输过来的。
示例:
QSqlQuery query("SELECT country FROM artist");
while (query.next()) {
QString country = query.value(0).toString();
doSomething(country);
}
要想访问由一个查询所返回的数据的话,就使用value(int)。由一个 SELECT 语句返回的数据中的每个字段都是通过将那个字段在语句中的位置传递给前面所说的那个函数来访问的,字段位置从0 开始。从这一点来看,是不建议使用 SELECT * 查询的,因为返回的字段的顺序是不确定的。
为咯效率上的考虑,没有提供按照名字来访问字段的函数(除非你使用预处理的(prepared)带有名字的查询,下面会说到)。要将一个字段名字转换成索引(index)的话,就使用 record (). indexOf() ,例如:
QSqlQuery query("SELECT * FROM artist");
int fieldNo = query.record().indexOf("country");
while (query.next()) {
QString country = query.value(fieldNo).toString();
doSomething(country);
}
QSqlQuery支持执行预处理的查询,以及将参数的值与占位符绑定。某些数据库不支持这些特性,所以,对于那些数据库,Qt会模仿(emulates)那些必要的功能。例如,Oracle和ODBC驱动程序提供咯可用的预处理查询的支持,因此Qt 直接使用它们的功能;但是对于那些不支持这个功能的数据库勒,Qt会自己实现这个特性,比如说,在一个查询被执行的时候将占位符替换成实际的值。使用 numRowsAffected ()来获知有多少行被一个非 SELECT 查询影响,使用 size ()来获知一个 SELECT 查询返回咯多少行数据。
Oracle数据库使用“ 冒号 名字 ”的语法来识别占位符,比如说 :name 。ODBC简单地使用 ? 字符。Qt同时支持这两种语法,只是有一个限制:你不能将它们在同一个查询中混合使用。
你可以使用 boundValues ()来将所有字段的值提取到单个变量(一个映射(map))中。
在下面,我们展示的是同一个例子,其中使用咯四种绑定方法中的每一种,并且还有一个例子是将值绑定到一个存储过程的。
使用命名(named)的占位符进行的命名(Named)绑定:
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();
使用命名占位符进行的位置(Positional)绑定:
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();
将值绑定到一个存储过程中:
这段代码调用一个叫做 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是65
注意:被解除绑定(unbound)的参数会保持它们的值。
那些使用return 语句来返回值,以及那些返回多个结果集的存储过程是不被完全支持的。要想了解特定的细节的话,参见 SQL数据库驱动 。
警告:你必须在创建QSqlQuery 之前载入SQL 驱动并且打开连接。另外,在这个查询存在的时间中,连接必须保持为打开状态;否则,QSqlQuery 的行为是不可预知的。
参见 QSqlDatabase 、 QSqlQueryModel 、 QSqlTableModel 和 QVariant 。
使用数据库 db 来构造一个 QSqlQuery 对象。如果 db 是无效的,那么就会使用程序的默认数据库。
参见 QSqlDatabase 。
返回在这个查询中发生的上个错误(如果有的话)的错误信息。
参见 QSqlError 和 QSqlDatabase::lastError ()。
HxLauncher: Launch Android applications by voice commands