Tuesday, November 4, 2014

SQL Backup Job

In the past I've made jobs that iterate through every user database and run a backup query.  The problem with this is it doesn't give much feedback about what's going on.  I decided to expand on this concept and have the job create new steps for every new database that's added.  The job history will give some more details about what step failed while allowing it to complete every step. Anyway here's what I've come up with (note, you'll have to create the job first, then get the job id. Also you should add a terminating step before running the first time):


DECLARE @strDBName VARCHAR(200)
DECLARE @strSQL NVARCHAR(1000);

DECLARE myCursor CURSOR FOR
SELECT NAME AS DB
FROM sys.databases
WHERE state_desc='ONLNE'
    AND name NOT IN ('master', 'model', 'msdb', 'tempdb');

OPEN myCursor
FETCH NEXT FROM myCursor INTO @strDBName
WHILE @@FETCH_STATUS = 0
BEGIN
IF NOT EXISTS
    (
    SELECT 1
    FROM msdb.dbo.sysjobs j
    JOIN msdb.dbo.sysjobsteps js ON js.job_id = j.job_id
    JOIN master.dbo.sysservers s ON s.srvid=j.originating_server_id
    WHERE js.command LIKE '%' + @strDBName + '%'
    )
    BEGIN
        DECLARE @stepname NVARCHAR(100);
        SET @stepname = N'Backup ' + @strDBName;
        DECLARE @commandtext NVARCHAR(2000);
        SET @commandtext = N'DECLARE @date VARCHAR(10);
DECLARE @path NVARCHAR(200);
SET @date=format(getdate(),''yyyyMMdd'');
SET @path=N''[YOUR BACKUP PATH]' + @strDBName + ''' + @date + ''.bak'';
BACKUP Database [' + @strDBName + ']
    TO DISK = @path
    WITH FORMAT';
        EXEC msdb.dbo.sp_add_jobstep @job_id='[THE ID OF THIS JOB]',
            @step_name=@stepname,
            @step_id=2,
            @subsystem='TSQL',
            @command=@commandtext,
            @database_name=@strDBName,
            @on_success_action=3,
            @on_fail_action=3
    END
    FETCH NEXT FROM myCursor INTO @strDBName
END
CLOSE myCursor
DEALLOCATE myCursor
DECLARE @laststep int;
SELECT @laststep = count(*)
FROM msdb.dbo.sysjobs j
JOIN msdb.dbo.sysjobsteps js ON js.job_id = j.job_id
JOIN master.dbo.sysservers s ON s.servid=j.originating_server_id
WHERE j.job_id = '[THE ID OF THIS JOB]'

EXEC msdb.dbo.sp_update_jobstep @job_id='[THE ID OF THIS JOB]'
    @step_id=@laststep,
    @on_fail_action = 2,
    @on_success_action = 1;

One note, the first time you run this it will create the steps but it will only run the steps that existed when the job started running, So the next time the job runs it will use all the steps.

Some things I still want to work out are if a DB goes offline or is removed, I should remove that step...but that's for later.


No comments:

Post a Comment