警告

本节包含从C++自动翻译到Python的代码片段,可能包含错误。

执行SQL语句

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

下一节中描述的QSqlQueryModelQSqlTableModel类为访问数据库提供了更高级的接口。如果您不熟悉SQL,您可能想直接跳到下一节(使用SQL模型类)。

执行查询

要执行SQL语句,只需创建一个QSqlQuery对象并调用exec(),如下所示:

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

QSqlQuery 构造函数接受一个可选的 QSqlDatabase 对象,该对象指定要使用的数据库连接。在上面的示例中,我们没有指定任何连接,因此使用了默认连接。

如果发生错误,exec() 返回 false。然后可以通过 lastError() 获取错误信息。

插入、更新和删除记录

QSqlQuery 可以执行任意的SQL语句,不仅仅是 SELECT。以下示例使用 INSERT 向表中插入一条记录:

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

如果你想同时插入多条记录,通常更有效的方法是将查询与实际插入的值分开。这可以通过使用占位符来实现。Qt支持两种占位符语法:命名绑定和位置绑定。以下是命名绑定的示例:

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

这是一个位置绑定的示例:

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

两种语法都适用于Qt提供的所有数据库驱动程序。如果数据库本身支持该语法,Qt会直接将查询转发给DBMS;否则,Qt会通过预处理查询来模拟占位符语法。最终由DBMS执行的实际查询可以通过executedQuery()获取。

当插入多条记录时,你只需要调用一次prepare()。然后根据需要多次调用bindValue()addBindValue(),接着调用exec()

除了性能之外,占位符的一个优势是你可以轻松指定任意值,而不必担心转义特殊字符。

更新记录类似于将其插入表中:

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

您还可以使用命名或位置绑定将参数与实际值关联起来。

最后,这里是一个DELETE语句的示例:

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

交易

如果底层数据库引擎支持事务,hasFeature ( Transactions ) 将返回 true。你可以使用 transaction() 来启动一个事务,然后是在事务上下文中执行的 SQL 命令,最后是 commit()rollback()。使用事务时,必须在创建查询之前启动事务。

示例:

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

QSqlDatabase.database().commit()

事务可用于确保复杂操作的原子性(例如,查找外键并创建记录),或提供在中间取消复杂更改的手段。