3

我需要在一个线程中同步运行 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 和其他数据库的建议当然也很有趣,但在我的情况下是次要的。

4

2 回答 2

1

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

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

DAL 需要让您访问它。

  • DAL:我知道AnyDAC 可以,但从未尝试过 ODBC。您的问题表明 ODBC API 支持它,但我不确定 Delphi ODBC 包装器是否会显示它。
  • 数据库服务器:至少 Oracle 和 SQL Server 支持这一点。
于 2013-02-16T20:31:47.253 回答
0

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

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

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

于 2013-02-18T09:31:26.357 回答