c++ - 如何取消长时间运行的 QSqlQuery?

标签 c++ qt5 qsqlquery qsqldatabase

如何取消长时间运行的QSqlQuery?

数据库正在返回超过 300 万行,并且显示在 QTableView 控件中。我希望能够强制停止这两个长时间操作:

  1. 当数据库正在运行一个长时间的操作时
  2. 如果数据库速度很快,但是有大量的行要返回并且处理/复制/显示这些需要很多时间

第二点,可以通过不使用QSqlQueryModel来解决。在这种情况下,手动解析查询结果可以分阶段完成,这将实现,但我也想知道移动数据 DB->QTableView 的过程是否可以中断和取消。

我试过以下但没有成功:

  • QSqlQuery::finish()
  • QFuture::取消()
  • QSqlDatabase.close() -- 这个会导致应用程序崩溃

如果需要完整的上下文,它是 here .有问题的方法是

on_button_stopQuery_released

最佳答案

在执行期间中止查询(不是获取,这是 QSqlQuery::finish 所做的)在所有数据库中都是偶然的。 Qt 本身不支持这个;解决方法将特定于后端。

例如,使用 PostgreSQL,您可以执行以下操作:

  • 在您的原始连接中,检索连接 ID (SELECT pg_backend_pid();) 并保存
  • 当您想中止查询时,打开第二个连接并通过发出 SELECT pg_cancel_backend(saved_id);
  • 终止查询

SQLite 有 sqlite3_interrupt(sqlite3*)。这会中断查询并且不会关闭连接。

MySQL 类似于 PostgreSQL:

  • 首先检索连接 ID (SELECT CONNECTION_ID();)
  • 然后通过另一个连接终止它 (KILL [CONNECTION|QUERY] $connection_id)。

如您所见,即使提供的功能也是特定于后端的。 Postgres 只能中止连接,而 SQLite 只能中止查询。因此,实现这一点的最简单方法是在查询中止且连接仍然有效时丢弃连接。然后你可以有一个简单的双 API 接口(interface)来进行取消管理(伪代码,即 Python):

class IConnectionCancellation:
    def register(connection):
        # save/retrieve connection ID

    def cancel():
        # open second connection, send backend-specific query

对于大型结果集,请考虑在模型中使用 canFetchMorefetchMore。这样您就不必在向用户显示某些结果之前处理整个结果集;使用起来可能会感觉更顺畅。由于例如,对固有的查询执行延迟没有帮助。当然,order by 或 grouping 子句。

关于c++ - 如何取消长时间运行的 QSqlQuery?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51801513/

相关文章:

c++ - QT 5.2.1 编译错误; 'delete' 之前的预期不合格 ID

c++ - 如何显示与系统不同区域设置的 QDate-month?

c++ - QPushButton 未显示在 QTableView 上(使用 QItemDelegate 过程)

c++ - QSqlquery prepare() 和 bindvalue() 不工作?

c++ - 需要有关 C++ 模板的帮助

c++ - 什么是默认方法以及如何正确使用它们?

c++ - 对视频流进行字节级数据纠错

mysql - 从 ID 列返回重复 ID 的计数

mysql - 如何从特定数量的行中进行选择?

c++ - 为什么我不能向下转换指向模板参数中成员的指针?