Good way to call multiple SQL Server Agent jobs sequentially from one main job?

SQL Sentry has a facility built exactly for this: to chain jobs and arrange them in various workflow orders.

I started using SQL Sentry years ago, before I ever joined the company, to do exactly this. What I wanted was a way to start a restore job on our test server immediately after the backup on production had finished.

What I had originally implemented was just a substantial buffer between the backup job start time and the restore start time. This wasn't exactly foolproof; since backup times varied the buffer often left us with wasted time where a restore hadn't started even though it could have. And occasionally the buffer wasn't enough.

What I implemented next was similar to what you have - I wrote a job on the test server that started shortly after the scheduled backup, and kept polling to see when the job was finished. That was later amended to just have a second step in the backup job that updated a table on the test server. Not really much different, except the restore job only had to watch a table locally instead of monitoring the job history remotely. Thinking back this could have been a trigger on that table that called sp_start_job so the job didn't have to run every n minutes (or be scheduled at all).

The final solution was to chain jobs together ... when the backup on server A finishes, Event Manager starts the restore job on server B. And if there was a third job, and a fourth job, or conditional logic based on what to do when a job fails vs. succeeds, etc., this can all be accounted for. The workflow designer will remind you quite a bit of SSIS:

enter image description here

The underlying mechanics of what I'm describing is not rocket surgery, of course. You could write this type of chaining wrapper yourself if you sat down and did it. Just providing you one alternative where you don't have to.


The main problem with your approach is that you have to continually loop round until something happens (which could be an awfully long time or even never) and that doesn't quite feel right. Which is why I guess you're asking the question.

So, how about using a data-driven approach to your problem? For example, create an 'audit' table that each job writes to as it starts and finishes:

Job Name | Start Time        | End Time
---------+-------------------+------------------
Test1      2012-07-26 07:30    2012-07-26 07:35

Create a 'processing' table that lists all the jobs and the order that they need to be executed in:

Job Name | Run Order
---------+---------
Test1    | 1
Test2    | 2
Test3    | 3

Create an insert trigger on the audit table, so that when a job completes and the audit record is inserted, the trigger queries the processing table for the next job (by Run Order) and then launches it.

The benefits to this approach are:

  1. It is fairly simple to develop and maintain.
  2. It gives the ability to add new jobs or change the order of existing jobs via the processing table without having to change a line of code.
  3. The audit table gives some visibility as to when things have happened.
  4. It doesn't waste CPU cycles. The trigger will only fire when something has happened.
  5. It feels right

HTH