1つのメインジョブから複数のSQL Serverエージェントジョブを順番に呼び出す良い方法は?


11

順次実行する必要があるSQL Serverエージェントジョブがいくつかあります。実行する必要があるジョブの概要をわかりやすくするために、への呼び出しで他のジョブを呼び出すメインジョブを作成しましたEXEC msdb.dbo.sp_start_job N'TEST1'。はsp_start_job即座に終了しますが(ジョブステップ1)、TEST1次のジョブを呼び出す前に、ジョブが終了するまでメインジョブを待機させます。

そのため、ジョブが呼び出された直後に実行を開始し(ジョブステップ2)、メインジョブを強制的にサブジョブが完了するまで待機させる次の小さなスクリプトを記述しました。

WHILE 1 = 1
  BEGIN
    WAITFOR DELAY '00:05:00.000';

    SELECT *
    INTO   #jobs
    FROM   OPENROWSET('SQLNCLI', 'Server=TESTSERVER;Trusted_Connection=yes;',
           'EXEC msdb.dbo.sp_help_job @job_name = N''TEST1'',
           @execution_status = 0, @job_aspect = N''JOB''');

    IF NOT (EXISTS (SELECT top 1 * FROM #jobs))
      BEGIN
        BREAK
      END;

    DROP TABLE #jobs;

  END;

これは十分に機能します。しかし、私はよりスマートで安全な(WHILE 1 = 1?)ソリューションが可能なはずだと感じました。

次の点に興味があります。洞察を提供していただければ幸いです。

  • このアプローチの問題は何ですか?
  • これを行うためのより良い方法を提案できますか?

(私はコードの改善に焦点を合わせていたので、私は最初にこの質問をStackOverflowに投稿しました。それでも有効です。しかし、私の考えでは、ここにいる人々は一般に、私がこれをやろうとしない方がいい理由について、もっと賢いことを言うでしょう。 mすぐに実行するか、適切な代替手段を提供します。)

編集(7月25日)
どうやら私のスクリプトにはそれほど問題はありません。それに関する問題を指摘する回答の数が少ないためです:-)この種のスクリプトの代替手段は、これらのために設計されたツールを使用することですタスク(SQL Sentry Event Managerまたは...など)-または自分でそのようなツールを作成する。現在の会社ではそのようなツールを購入することはないので、ここではスクリプトのみを使用します。


これらのジョブを独立したジョブではなく、メインジョブのステップとして検討したことはありますか?これにより、特に、このようにシーケンスで一緒に呼び出されるだけの場合は、複雑さが軽減されます...
アーロンベルトラン

それはバランスです。すべてのジョブをメインジョブのステップとして追加すると、「クリーンな」メンテナンスになりますが、その場合、多くの概要と特定のジョブを手動で実行する可能性が失われます。したがって、私は確かにそれを検討しましたが、現在の「解決策」には、それが機能する限り、あまりにも多くの利点があります。

回答:


9

免責事項:私はSQL Sentryで働いています。

私たちのSQL Sentryのイベントマネージャの製品はこのために、正確に構築された施設があります。チェーン・ジョブを、さまざまなワークフローの順序でそれらを配置します。

私が入社する前の何年か前にSQL Sentryを使い始め、まさにこれを実現しました。私が欲しかったのは、運用環境でのバックアップが完了した直後にテストサーバーで復元ジョブを開始する方法でした。

私が最初に実装したのは、バックアップジョブの開始時刻と復元の開始時刻の間の単なるバッファでした。これは完全に簡単というわけではありませんでした。バックアップ時間は変動するため、バッファは、たとえそれが可能であったとしても、リストアが開始されなかったという無駄な時間をしばしば私たちに残しました。そして、時々バッファが十分ではなかった。

次に実装したものは、あなたが持っているものに似ていました-スケジュールされたバックアップの直後に開始するジョブをテストサーバーに書き込み、ポーリングを続けてジョブがいつ終了したかを確認しました。その後、テストサーバーのテーブルを更新するバックアップジョブに2つ目の手順が追加されました。それほど大きな違いはありませんが、復元ジョブは、リモートでジョブ履歴を監視するのではなく、ローカルでテーブルを監視するだけで済みました。これを思い出すと、テーブルが呼び出されsp_start_jobてn分ごとにジョブを実行する(またはスケジュールする)必要がなくなりました。

最終的な解決策は、ジョブをチェーン化することでした...サーバーAでのバックアップが完了すると、イベントマネージャーはサーバーBで復元ジョブを開始します。ジョブが失敗したときと成功したときなど、これはすべて説明できます。ワークフローデザイナーは、かなりのSSISを思い出させます。

ここに画像の説明を入力してください

私が説明しているものの根本的なメカニズムは、もちろんロケット手術ではありません。あなたが座ってそれをしたなら、あなたは自分でこのタイプの連鎖ラッパーを書くことができます。必要のない代替手段を1つ提供するだけです。


2

あなたのアプローチの主な問題は、何かが起こるまで(それはひどく長い時間かもしれないし、まったく起こらないかもしれない)継続的にループを繰り返さなければならず、それがまったく正しく感じられないということです。これが、あなたが質問していると思います。

では、データ駆動型のアプローチを使用して問題を解決してみませんか?たとえば、各ジョブが開始および終了するときに書き込む「監査」テーブルを作成します。

ジョブ名| 開始時間| 終了時間
--------- + ------------------- + ------------------
テスト1 2012-07-26 07:30 2012-07-26 07:35

すべてのジョブとそれらを実行する必要がある順序をリストする「処理」テーブルを作成します。

ジョブ名| 実行順序
--------- + ---------
Test1 | 1
Test2 | 2
Test3 | 3

監査テーブルに挿入トリガーを作成します。これにより、ジョブが完了して監査レコードが挿入されたときに、トリガーが次のジョブを(実行順序によって)処理テーブルに照会し、それを起動します。

このアプローチの利点は次のとおりです。

  1. 開発と保守はかなり簡単です。
  2. コード行を変更せずに、処理テーブルを介して新しいジョブを追加したり、既存のジョブの順序を変更したりできます。
  3. 監査テーブルは、物事がいつ起こったかについてある程度の可視性を提供します。
  4. CPUサイクルを無駄にしません。トリガーは、何かが発生したときにのみ起動します。
  5. それは感じている右😉

HTH


1
どうもありがとう、あなたの答えが大好きです!ぜひやってみます!
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.