0

sp_start_job を使用して 10 個の他のジョブを呼び出す SQL Server ジョブがあります。ジョブには 10 のステップがあり、各ステップは再びサブジョブを呼び出します。

メイン ジョブを実行すると、ステップ 1 から開始され、数秒後に「正常に完了しました」と表示されます。

しかし、ジョブの実行には時間がかかり、ログ情報を確認すると、数時間後に終了するまで、10 個のステップすべてが同時に実行されていることが示されます。

私の要件は、最初にステップ 1 を終了してからステップ 2 を開始することです。

4

2 に答える 2

1

Microsoft Codeフォーラムには、ストアド プロシージャが実行されているかどうかを確認する方法があります。これを使用して、ジョブが完了するまで待つことができます。

while 1=1
    begin
    WAITFOR DELAY '000:00:10'

    if not exists (
        SELECT *
        FROM master..sysprocesses p
        JOIN msdb..sysjobs j ON 
            substring(left(j.job_id,8),7,2) + 
            substring(left(j.job_id,8),5,2) +
            substring(left(j.job_id,8),3,2) + 
            substring(left(j.job_id,8),1,2) =
            substring(p.program_name,32,8)
        WHERE j.name = 'YourJobName'
        AND program_name like 'SQLAgent - TSQL JobStep (Job %'
    )
        break
    end

コードはこのように動作し、10 秒間待機してから、ジョブ YourJobName が実行されているかどうかを確認します。ジョブが実行されなくなるまで、それが繰り返されます。これを sp_start_job 呼び出しの間に入れることができます。

そうは言っても、もっと簡単な方法があるはずです。10 個のジョブのそれぞれのコードをストアド プロシージャに格納できませんか? 「マスター」ジョブは、10 個のジョブを開始する代わりに、10 個のストアド プロシージャを呼び出すことができます。

于 2009-10-28T09:40:18.253 に答える
0

私の最初の答えは、上記のようにループを使用できますが、msdbのジョブ履歴テーブルをチェックして、前のジョブが終了するのを待つというものでした。

select  sj.name as job_name
from    msdb.dbo.sysjobhistory sjh
    inner join msdb.dbo.sysjobs_view sj on sj.job_id = sjh.job_id
where   sjh.step_id = 0 --Job outcome
    and sjh.run_status = 4 --In progress

Andomar、これについて質問してくれてありがとう。sysjobhistoryは、最初のステップが完了した後にのみ更新されることがわかりました。run_statusの1つの値が「進行中」の場合、ステップの開始時にテーブルを更新する必要があると想像するのはばかだけです。私は周りを検索しましたが、これは難しい問題のようです。どこかでSQLは何が起こっているかを知っていますが、情報をあまり公開していません。

何マイルもの複雑なコードを使用するか、文書化されていないストアドプロシージャを使用するかを選択する必要があるようです。sysjobhistoryのグーグルによって、コードの答えのマイルを簡単に見つけることができます-いくつかあります-。個人的に私はxpアプローチを好みます:

create table #xp_results(
    job_id uniqueidentifier not null,
    last_run_date int not null,
    last_run_time int not null,
    next_run_date int not null,
    next_run_time int not null,
    next_run_schedule_id int not null,
    requested_to_run int not null, -- bool
    request_source int not null,
    request_source_id sysname collate database_default null,
    running int not null, -- bool
    current_step int not null,
    current_retry_attempt int not null,
    job_state int not null )

insert #xp_results exec master.dbo.xp_sqlagent_enum_jobs @is_sysadmin = 1, @job_owner = ''

select  sj.name
from    #xp_results xpr
    inner join msdb.dbo.sysjobs_view sj on sj.job_id = xpr.job_id
where running = 1

drop table #xp_results

私はこれをテストしました、そしてそれは本当にうまくいくようです。このxpを使用するのは危険かもしれませんが、これがJob Activity Monitorが使用するものです(プロファイラーをオンにして実行しました)。したがって、変更された場合は、この情報を見つける他の方法が提供される可能性があります。このコードを関数またはprocにまとめて、依存関係があることを文書化する限り、私にとっては多くの悪の中で最も少ないように思えます。

于 2009-10-28T19:40:30.007 に答える