Create SQL Server job automatically

前端 未结 5 1490
北恋
北恋 2020-12-18 12:27

I am writing SQL Server deployment scripts which create SQL Server job automatically on a specific SQL Server server/instance. I have found that I can extract the sql statem

相关标签:
5条回答
  • 2020-12-18 12:36

    I was coming across the same problem today and how I tackle it is so simple Do the following

    1. Create a stored proc that creates the job with parameter @serverName nvarchar(128)

      Create Proc CreateAJob(@serverName nvarchar(128))
      
    2. Now easy, you can get the server name using the following

      Declare @serverName nvarchar(128)
      SELECT @servername=@@SERVERNAME
      
    3. Execute the stored proc to create your job

      EXEC CreateJob @serverName
      

    That is it.

    I am using visual studio db project and I did steps 2 and 3 int the postdeployment script

    0 讨论(0)
  • 2020-12-18 12:42

    Futher to BrianD's answer above, you can define variables (actually more like preprocessor macros than variables) at the sqlcmd level; these are enclosed in parentheses with a leading $ sign:

    SET @JobName = '$(JobName)'
    SET @Owner = '$(Owner)'
    

    This allows you to pass the information on the command line to sqlcmd with the -v switch:

    sqlcmd -... -i create_jobs.sql -v JobName=Job1 -v Owner=BrianD
    
    0 讨论(0)
  • 2020-12-18 12:48

    Using the example from BrainD I'd like to point out that his idea of using variables is just fine, however, passing them to the stored procedures using dymanic SQL most certainly isn't the right approach. Rather, use the parameters of the stored procedures to directly pass the variables directly to where they are needed.

    DECLARE @JobName VARCHAR(20)  --Job Name
    DECLARE @Owner VARCHAR(200)   --Job Owner
    DECLARE @DBName VARCHAR(200)  --Database Name
    DECLARE @JobCode VARCHAR(4000) --Create Statement for Job
    SET @JobName = 'Test2'
    SET @Owner = 'BrianD'
    SET @DBName = 'master'
    
    BEGIN TRANSACTION
    DECLARE @ReturnCode INT
    SELECT @ReturnCode = 0
    IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)
    BEGIN
    EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]'
    IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
    END
    DECLARE @jobId BINARY(16)
    EXEC @ReturnCode =  msdb.dbo.sp_add_job @job_name= @JobName, 
            @enabled=1, 
            @notify_level_eventlog=0, 
            @notify_level_email=0, 
            @notify_level_netsend=0, 
            @notify_level_page=0, 
            @delete_level=0, 
            @description=N'No description available.', 
            @category_name=N'[Uncategorized (Local)]', 
            @owner_login_name= @Owner, 
            @job_id = @jobId OUTPUT
    IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
    EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Version and Prod Level', 
            @step_id=1, 
            @cmdexec_success_code=0, 
            @on_success_action=1, 
            @on_success_step_id=0, 
            @on_fail_action=2, 
            @on_fail_step_id=0, 
            @retry_attempts=0, 
            @retry_interval=0, 
            @os_run_priority=0, @subsystem=N'TSQL', 
            @command=N'select SERVERPROPERTY(''productversion''), SERVERPROPERTY(''productlevel'')', 
            @database_name=@DBName, 
            @flags=0
    IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
    EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
    IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
    EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
    IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
    COMMIT TRANSACTION
    GOTO EndSave
    QuitWithRollback:
        IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
    EndSave:
    GO
    
    0 讨论(0)
  • 2020-12-18 12:50

    You would need to dynamically create the job script and then execute it. You could try something like the following or change this to a stored proc with input parameters for the job owner and database name.

    DECLARE @JobName VARCHAR(20)  --Job Name
    DECLARE @Owner VARCHAR(200)   --Job Owner
    DECLARE @DBName VARCHAR(200)  --Database Name
    DECLARE @JobCode VARCHAR(4000) --Create Statement for Job
    SET @JobName = 'Test2'
    SET @Owner = 'BrianD'
    SET @DBName = 'master'
    SET @JobCode = 'USE msdb
    GO
    BEGIN TRANSACTION
    DECLARE @ReturnCode INT
    SELECT @ReturnCode = 0
    IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N''[Uncategorized (Local)]'' AND category_class=1)
    BEGIN
    EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N''JOB'', @type=N''LOCAL'', @name=N''[Uncategorized (Local)]''
    IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
    END
    DECLARE @jobId BINARY(16)
    EXEC @ReturnCode =  msdb.dbo.sp_add_job @job_name=N''' + @JobName + ''', 
            @enabled=1, 
            @notify_level_eventlog=0, 
            @notify_level_email=0, 
            @notify_level_netsend=0, 
            @notify_level_page=0, 
            @delete_level=0, 
            @description=N''No description available.'', 
            @category_name=N''[Uncategorized (Local)]'', 
            @owner_login_name=N''' + @Owner + ''', @job_id = @jobId OUTPUT
    IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
    EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N''Version and Prod Level'', 
            @step_id=1, 
            @cmdexec_success_code=0, 
            @on_success_action=1, 
            @on_success_step_id=0, 
            @on_fail_action=2, 
            @on_fail_step_id=0, 
            @retry_attempts=0, 
            @retry_interval=0, 
            @os_run_priority=0, @subsystem=N''TSQL'', 
            @command=N''select SERVERPROPERTY(''''productversion''''), SERVERPROPERTY(''''productlevel'''')'', 
            @database_name=N''' + @DBName + ''', 
            @flags=0
    IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
    EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
    IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
    EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N''(local)''
    IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
    COMMIT TRANSACTION
    GOTO EndSave
    QuitWithRollback:
        IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
    EndSave:
    GO'
    Exec (@JobCode)
    

    Hopefully this will get you going in the right direction. If you need more help let me know.

    0 讨论(0)
  • 2020-12-18 12:55

    I even got it better ...Create a stored procedure without a parameter and inside of the stored proc do :

       Declare @serverName nvarchar(128)
       SELECT @servername=@@SERVERNAME
    

    Then assign @servername to the server_name parameter of sp_add_jobserver as in below:

    msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name =@serverName
    

    In order to create stored proc that creates a sql job, first create it using the sql management studio and then right click on the job and do Drop and Create....

    0 讨论(0)
提交回复
热议问题