web-dev-qa-db-ja.com

ストアドプロシージャを起動して、終了するのを待たずにすぐに戻ることはできますか?

ユーザーが手動で実行できるストアドプロシージャがあり、1日中絶えず使用されるレポートの更新された数値を取得できます。

最初のストアドプロシージャから取得した数値に基づいているため、最初のストアドプロシージャの実行後に実行する必要がある2番目のストアドプロシージャがありますが、実行に時間がかかり、別のプロセスのため、実行したくありません。この2番目のストアドプロシージャが実行されるまでユーザーを待機させます。

1つのストアドプロシージャで2番目のストアドプロシージャを開始し、結果を待たずにすぐに戻る方法はありますか?

SQL Server 2005を使用しています。

41
Rachel

これを達成する方法は複数あるようですが、最も簡単な方法は、SQLジョブでプロシージャを設定し、非同期でそれを開始する Martinの提案sp_start_job であることがわかりました=ストアドプロシージャからのコマンド。

EXEC msdb.dbo.sp_start_job @job_name='Run2ndStoredProcedure'

ストアドプロシージャのパラメーターを指定する必要がないため、これは私にのみ機能します。

状況に応じて機能する可能性がある他の提案は次のとおりです

  • SQL Service Broker - MartinSebastian のように使用することをお勧めします。これは、設定とその仕組みの学習の複雑さを気にしないのであれば、おそらく最良の提案です。
  • Mr.Brownstone推奨 のように、ストアドプロシージャの実行を担当するコードでプロセスを非同期に実行します。

    悪い考えではありませんが、私の場合、ストアドプロシージャは複数の場所から呼び出されるため、それらすべての場所を見つけて、2番目のプロシージャも確実に呼び出せるようにするのはそれほど現実的ではないようです。また、2番目のストアドプロシージャはかなり重要であり、2番目のストアドプロシージャを実行し忘れると、会社にいくつかの大きな問題を引き起こす可能性があります。

  • 最初の手順でフラグを設定し、そのフラグをチェックして、設定されている場合は Jimboが推奨 のように実行する繰り返しジョブをセットアップします。私は絶えず実行され、数分ごとに変更をチェックするジョブの大ファンではありませんが、状況に応じて検討する価値のあるオプションです。
28
Rachel

この古い質問は、より包括的な答えに値します。これらの一部はここの他の回答/コメントで言及されていますが、他はOPの特定の状況で機能する場合と機能しない場合がありますが、ストアドプロシージャをSQLから非同期で呼び出すことを求める他の人には機能する場合があります。

完全に明示的に:TSQLはしない(それ自体)他のTSQL操作を非同期で起動する機能があります

それはあなたがまだたくさんの選択肢がないということではありません:

  • SQLエージェントジョブ:複数のSQLジョブを作成し、必要なときに実行するようにスケジュールするか、「マスターコントロール」ストアドプロシージャから非同期に開始しますsp_start_jobを使用します。プログラムで進捗状況を監視する必要がある場合は、ジョブがそれぞれカスタムJOB_PROGRESSテーブルを更新することを確認してください(または、ドキュメントに記載されていない関数xp_sqlagent_enum_jobsを使用して、ジョブがまだ終了しているかどうかを確認できます この優れた記事 (Gregory A. Larsenによる)。パラメータが異なる同じストアドプロシージャを実行している場合でも、並列プロセスを実行するのと同じ数の個別のジョブを作成する必要があります。
  • SSISパッケージ:より複雑な非同期シナリオでは、単純な分岐タスクフローでSSISパッケージを作成します。 SSISはこれらのタスクを個別のspidで起動し、SQLは並列で実行します。 SQLエージェントジョブからSSISパッケージを呼び出します。
  • カスタムアプリケーション:選択した言語(C#、Powershellなど)で、その言語が提供する非同期メソッドを使用して簡単なカスタムアプリを記述します。各アプリケーションスレッドでSQLストアドプロシージャを呼び出します。
  • OLEオートメーション:SQLでは、sp_oacreateおよびsp_oamethodを使用して、他のストアドプロシージャを呼び出す新しいプロセスを起動します- この記事 、同じくGregory A. Larsen。
  • Service BrokerService Brokerこの記事の非同期実行の良い例 の使用を検討してください。 。
  • CLR並列実行この記事 で説明されているように、CLRコマンドParallel_AddSqlおよびParallel_Executeを使用しますAlan Kaplan(SQL2005 +のみ)。
  • スケジュールされたWindowsタスク:完全を期すためにリストされていますが、私はこのオプションのファンではありません。

私の場合、おそらく、より単純なシナリオでは複数のSQLエージェントジョブを使用し、より複雑なシナリオではSSISパッケージを使用します。

あなたの場合、SQLエージェントジョブの呼び出しは、単純で扱いやすい選択のように聞こえます。

1つの最後のコメント:SQLは、可能な場合は常に個々の操作を並列化しようとしています*。つまり、2つのタスクを連続して実行するのではなく、同時に実行しても、すぐに終了する保証はありません。それが実際に何か改善するかどうかを確認するために注意深くテストしてください。

DTSパッケージを同時に作成して8つのタスクを実行する開発者がいました。残念ながら、これは4 CPUサーバーのみでした:)

*デフォルト設定を想定しています。これは、サーバーの最大並列度またはアフィニティマスクを変更するか、MAXDOPクエリヒントを使用して変更できます。

8
BradC

キューでのアクティベーションとともにService Brokerを使用できます。これにより、プロシージャコールのパラメータをキューにポストできます。挿入と同じくらいの時間がかかります。トランザクションがコミットされた後、さらに数秒かかる可能性があると、アクティベーションによって自動的に非同期でレシーバープロシージャが呼び出されます。単にwuoldよりも、キューのパラメーターを取り、必要な作業を行う必要があります。

8
Sebastian Meine

はい、1つの方法:

  1. 最初のストアドプロシージャが完了すると、2番目のストアドプロシージャの実行に必要なすべての情報を含むレコードが挿入されます
  2. 2番目のストアード・プロシージャーは、ジョブとして、毎分または決定した時刻に実行されます
  3. 挿入されたレコードをチェックし、そのプロセスを実行して、レコードに完了のマークを付けます
6
Jimbo

別の可能性は、1番目のストアドプロシージャが完了時に監査テーブルに書き込むようにし、2番目のストアドプロシージャを起動するトリガーを監査テーブルに配置することです。継続的にポーリングする必要はなく、追加のSQL Serverエージェントジョブも必要ありません。

1
paco