【问题标题】:How to cancel SQL in thread A from thread B using SQLCancel如何使用 SQLCancel 从线程 B 中取消线程 A 中的 SQL
【发布时间】:2013-02-16 02:33:55
【问题描述】:

我需要在一个线程中同步运行 SQL 命令,并能够取消另一个线程的查询。

据我所知,我需要 ODBC 函数 SQLCancel 和连接对象的句柄来完成这项任务。

但是,作为这个领域的新手,要弄清楚这一点感觉就像一场艰苦的战斗。

谁能提供我在 Delphi 2006 中实现此目的的示例代码?

设置说明:

线程 A

ODBC_Connection.Execute('SELECT a,b,c INTO ##MyTable FROM LongRunningQuery')

线程 B

[使用 SQLCancel 取消线程 A 中的 SQL 语句的一些神奇代码]

注意:我有一个当前的解决方案,我利用 ADOCommand 对象异步执行查询。这使得使用 Command 对象的 Cancel 方法成为可能。但这很慢,因为我有一个带有 Sleep 函数的 while 循环来轮询命令的状态以查看它何时完成。这就是为什么我想要一个基于同步执行的解决方案。我有数百个查询,所以性能很重要。

附加信息:我使用 SQL Server 作为后端,所以这是我正在寻找的主要解决方案。处理 Oracle 和其他数据库的建议当然也很有趣,但对我来说是次要的。

【问题讨论】:

  • 这是否可能是值得怀疑的。对于 Oracle,文档中明确说明 OCIBreak 可以从并行线程中使用。而 mySQL 或 PostgreSQL 使用 2nd session 来取消第一个任务。
  • @Ivan:根据 ODBC 文档和我在网上找到的许多 cmets,这不仅是可能的 - 这是实现它的方法。我只是希望我能自己弄清楚如何去做。 Delphi 的本机组件不支持它。正如你所说的和我在我的问题中所写的那样,它应该从另一个线程(会话)完成。
  • 正如我之前所说,至少 mySQL 和 PostreSQL 本身并不支持它。您必须从第二个会话执行“KILL PROCESS ”。
  • @Ivan:你能提供一个例子(代码)吗?
  • 对于MS SQL

标签: sql multithreading delphi odbc


【解决方案1】:

这完全取决于您的数据库后端、数据库客户端和您使用的 DAL。

数据库服务器和客户端必须支持从不同线程访问相同的底层连接和语句句柄。

DAL 需要让您访问它。

  • DAL:我知道AnyDAC does,但从未尝试过 ODBC。您的问题表明 ODBC API 支持它,但我不确定 Delphi ODBC 包装器是否显示它。
  • 数据库服务器:至少 Oracle 和 SQL Server 支持。

【讨论】:

    【解决方案2】:

    根据 ODBC 规范,SQLCancel 可以取消对语句的以下类型的处理:

    • 在语句上异步运行的函数(听起来好像已经完成了)
    • 需要数据的语句上的函数(例如返回 SQL_NEED_DATA 的 SQLExecute)
    • 在另一个线程上的语句上运行的函数(听起来这就是你想要的)

    我亲自完成了上面的前 2 个,但从来没有完成最后一个。您还需要一个线程安全的 ODBC 驱动程序(有些不是即使 ODBC 规范说它们应该是)。至于你如何在 Delphi 中做到这一点,我不知道。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-29
      • 1970-01-01
      • 2021-12-11
      • 1970-01-01
      • 1970-01-01
      • 2013-10-23
      • 1970-01-01
      • 2017-07-28
      相关资源
      最近更新 更多