3

別のスレッドからクエリをキャンセルする機能を使用して、1 つのスレッドで 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 は、ステートメントの次の種類の処理をキャンセルできます。

  • ステートメントで非同期に実行される関数 (既に実行済みのように聞こえます)
  • データを必要とするステートメントの関数 (例としては、SQL_NEED_DATA を返す SQLExecute があります)
  • 別のスレッドのステートメントで実行されている関数 (これが必要なように聞こえます)

私は個人的に上記の最初の 2 つを実行しましたが、最後のものは実行しませんでした。また、スレッドセーフな ODBC ドライバーも必要です (ODBC の仕様ではそうあるべきだとされていても、そうでないものもあります)。Delphi でこれを行う方法については、私にはわかりません。

于 2013-02-18T09:31:26.357 に答える