Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Data Management

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

    Search

    XML Feeds

    Google Ads

    « Answers To The SQL Server Quiz: Can You Answer All These PostSQL Server Quiz, Can You Answer All These? »
    comments

    Altering SQL Agent jobs during job runtime can give you some options as to how you can force other jobs
    to react based on events. There are a listing of system procedures in the MSDB database available for
    you to use so you can literally alter your entire timelines and schedules based on a failure, success or
    even OS or network related issues. Here is a basic example of disabling and enabling a job
    based on a monitoring task.

    In this example there is a requirement to monitor a table that is being used to monitor finish good allocation
    to a manufacturing facility to prevent volume from going over capacity.

    Job 1 performs a monitoring task every 30 minutes. Basically querying the table that holds the count of the volume
    the facility has received that day (starting at midnight). At midnight the volume is replenished by means of the value
    specified in the same table. There is a need to monitor the capacity and once under 2000 units are remaining,
    you are required to send notifications out to management. Notifications should go out once.
    The key is the one notification. This is one option of getting around that using the system procedures to alter job properties.

    Step 1) create the table to monitor

    1. SET ANSI_NULLS ON
    2. GO
    3. SET QUOTED_IDENTIFIER ON
    4. GO
    5. SET ANSI_PADDING ON
    6. GO
    7. CREATE TABLE [dbo].[VOL_MONITOR](
    8.     [VolumeID] [int] IDENTITY(1,1) NOT NULL,
    9.     [Facility] [varchar](50) NOT NULL,
    10.     [Volume] [int] NOT NULL,
    11.     [Vol_Status] [int] NOT NULL,
    12.  CONSTRAINT [PK_VOL_MONITOR] PRIMARY KEY CLUSTERED
    13. (
    14.     [VolumeID] ASC
    15. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF,
    16.             IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON,
    17.             ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
    18. ) ON [PRIMARY]
    19.  
    20. GO
    21. SET ANSI_PADDING OFF

    Insert the data in order to test out monitor

    1. INSERT INTO DBO.[VOL_MONITOR]
    2. VALUES ('AL Plant 1',20000,15000)

    Step 2) create the job to monitor the volume count.

    1. DECLARE @jobId BINARY(16)
    2. EXEC @ReturnCode =  msdb.dbo.sp_add_job @job_name=N'Capacity Restriction Monitor Plant 01',
    3.         @enabled=1,
    4.         @notify_level_eventlog=0,
    5.         @notify_level_email=0,
    6.         @notify_level_netsend=0,
    7.         @notify_level_page=0,
    8.         @delete_level=0,
    9.         @description=N'Monitors the levels of units allowe to be manufactured in plant 01.',
    10.         @category_name=N'[Uncategorized (Local)]',
    11.         @owner_login_name=N'{user}', @job_id = @jobId OUTPUT
    12. IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
    13. /****** Object:  Step [caller]    Script Date: 03/26/2009 08:31:35 ******/
    14. EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'caller',
    15.         @step_id=1,
    16.         @cmdexec_success_code=0,
    17.         @on_success_action=1,
    18.         @on_success_step_id=0,
    19.         @on_fail_action=2,
    20.         @on_fail_step_id=0,
    21.         @retry_attempts=0,
    22.         @retry_interval=0,
    23.         @os_run_priority=0, @subsystem=N'TSQL',
    24.         @command=N'if (select vol_status from VOL_MONITOR) <= 2000
    25.           Begin
    26.             EXEC msdb.dbo.sp_send_dbmail @recipients=''manager_group@companym.com'',
    27.                 @subject = ''Plant 01 volume reaching maximum capacity'',
    28.                 @body = ''Plant 01 volume reaching maximum capacity'',
    29.                 @body_format = ''HTML'',
    30.                 @profile_name = ''DBA01''
    31.           End',
    32.         @database_name=N'DBA05',
    33.         @flags=0
    34. IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
    35. EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
    36. IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
    37. EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'30 minutes',
    38.         @enabled=1,
    39.         @freq_type=4,
    40.         @freq_interval=1,
    41.         @freq_subday_type=4,
    42.         @freq_subday_interval=30,
    43.         @freq_relative_interval=0,
    44.         @freq_recurrence_factor=0,
    45.         @active_start_date=20090324,
    46.         @active_end_date=99991231,
    47.         @active_start_time=0,
    48.         @active_end_time=235959
    49. IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
    50. EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
    51. IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
    52. COMMIT TRANSACTION
    53. GOTO EndSave
    54. QuitWithRollback:
    55.     IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
    56. EndSave:

    So far we have successfully created a table to hold our capacity values that we negate based on units
    sent to eh facility and we have a job to monitor the capacity. Problem is the job will send out an
    email to management every 30 minutes which is not something managers like much. In order to keep the
    DBA from manually going in after the notification is sent we need to disable the job. We can
    use sp_udpate_job to get that task done.

    First query the sysjob table in MSDB to grab the job_id. You can also use the name of the job but I
    think that is prone to typos and copying the job_id directly out of sysjob is a bit more stable.

    1. select job_id,[name] from msdb.dbo.sysjobs

    This shows "8386ED61-E2A8-4DE5-B54C-4A7DFD3CDDEC" for the Capacity Restriction Monitor Plant 01 job_id

    Syntax for sp_update_job is as follows. One key note is you can use job_name or job_id to update the job with
    this system procedure BUT you cannot specify both. Other questions I hear are does the SP update other properties
    when you do not specify them. The answer is no, the SP will only update what parameter you specify.

    syntax

    1. sp_update_job [ @job_id =] job_id | [@job_name =] 'job_name'
    2.      [, [@new_name =] 'new_name' ]
    3.      [, [@enabled =] enabled ]
    4.      [, [@description =] 'description' ]
    5.      [, [@start_step_id =] step_id ]
    6.      [, [@category_name =] 'category' ]
    7.      [, [@owner_login_name =] 'login' ]
    8.      [, [@notify_level_eventlog =] eventlog_level ]
    9.      [, [@notify_level_email =] email_level ]
    10.      [, [@notify_level_netsend =] netsend_level ]
    11.      [, [@notify_level_page =] page_level ]
    12.      [, [@notify_email_operator_name =] 'email_name' ]
    13.           [, [@notify_netsend_operator_name =] 'netsend_operator' ]
    14.           [, [@notify_page_operator_name =] 'page_operator' ]
    15.      [, [@delete_level =] delete_level ]
    16.      [, [@automatic_post =] automatic_post ]

    So to form this call and disable the job we need to add to the job this statement.

    After the db mail send put issue a Go and then add

    1. Exec msdb.dbo.sp_update_job @job_id = '8386ED61-E2A8-4DE5-B54C-4A7DFD3CDDEC' , @enabled = 0

    Now when the job runs it will send the notifications out and disable the job so no further
    notifications will be sent.

    Every night at midnight we stated the volume should be replenished to the maximum allowed units. This is
    simply another job to reset the Vol_Status in our table to the value in Volume. The added requirement we need to
    add to that job is re-enabling out monitor. If we don't then the call to change the enable value in sysjob will remain
    0 and the we break out monitoring process. So create another job scheduled for midnight with the statement of

    1. Update mem_vol set vol_status = volume
    2. Go
    3. Exec msdb..sp_update_job @job_id = '8386ED61-E2A8-4DE5-B54C-4A7DFD3CDDEC' , @enabled = 1
    4. Go

    Now the process has gone through a complete cycle and the monitor and volume count starts clean.

    About the Author

    Ted Krueger is a SQL Server MVP and has been working in development and database administration for 13+ years. Specialties range from High Availability and Disaster / Recovery setup and testing methods down to custom assembly development for SQL Server Reporting Services. Ted blogs and is also one of the founders of LessThanDot.com technology community. Some of the articles focused on are Backup / Recovery, Security, SSIS and working on SQL Server and using all of the SQL Server features available to create stable and scalable database services. @onpnt
    Social SitingsTwitterLinkedInLTD RSS Feed
    3137 views
    Instapaper

    2 comments

    Comment from: Erik [Member] Email
    Erik Instead of doing the complicated stuff of altering jobs (which I admit could be really useful), it would be a lot simpler to just store the "last notified datetime" in a table, and only send the notification when the current date is greater than the last notified date. That way your scheduled task can run as often as you want but only one notification per day will be sent.

    Rather than using a "last notified datetime" it might make sense for someone to use "next notify datetime". It might also make sense to work in some logic so that a new notification goes out only after the alert-condition has gone through a false phase first. (Such as, once capacity is under 1000, no new notification can be sent until it has exceeded 1000 and then dropped under again). This can be done with a simple bit column. Combined with the "last notified datetime" you can fine tune your IF statement all you like and not need to modify jobs.
    03/26/09 @ 17:16
    Comment from: Qaisera [Visitor] · http://www.pakistanjobs.pk
    Qaisera I first time visit in this post. I find this post is very useful and workable.
    04/06/09 @ 22:28

    Leave a comment


    Your email address will not be revealed on this site.

    Your URL will be displayed.
    (Line breaks become <br />)
    (Name, email & website)
    (Allow users to contact you through a message form (your email will not be revealed.)