Quantcast
Channel: Eric Niemiec's Blog » SQL Server
Viewing all articles
Browse latest Browse all 10

How to backup all SQL Server Databases in an instance using sp_msforeachdb (set db owner, compatibility and recovery modes too)

$
0
0

If you need to make a quick backup of all databases in a single instance, you can make use of the built-in sp_msforeachdb procedure to iterate through all the databases in your instance and make a backup.  While I would not recommend this practice to be used as your ‘normal’ backup procedure, it is helpful when performing  maintenance tasks such as making a copy of production databases to move off to a dev server.

EXECUTE sp_msforeachdb 'USE [?]
IF DB_NAME() NOT IN(''master'',''msdb'',''tempdb'',''model'')
BACKUP DATABASE [?] TO DISK = ''C:\MyBaks\?.bak'' WITH INIT, COPY_ONLY, COMPRESSION'

This statement will back up all the databases except master, msdb, tempdb and model (which you may or may not want) to the location specified at c:\mybaks\.  This script specifies COPY_ONLY as to not disrupt your current backup chain along with COMPRESSION to make the files as small and portable as possible should your default settings no be configured to compress your backups.

To set your instance level default to compress backups, execute this statement:

EXEC sys.sp_configure N'backup compression default', N'1'
GO
RECONFIGURE WITH OVERRIDE
GO

There are many other uses of sp_msforeachdb, such as the following statement which sets all of your databases in to FULL recovery mode except for master, msdb, tempdb and model.  TempDB is the only database that you are not allowed to set in to FULL recovery mode – so it must be ignored.  Notice this script checks to make sure that the database is not already in FULL recovery mode before it changes it.

EXECUTE sp_msforeachdb '
IF (''?'' NOT IN(''master'',''msdb'',''tempdb'',''model''))
BEGIN
    IF (DATABASEPROPERTYEX (''?'', ''Recovery'') != N''FULL'')
        BEGIN
            EXECUTE sp_executesql N''ALTER DATABASE [?] SET RECOVERY FULL''
            PRINT ''Updated recovery mode of ? to FULL''
        END
    ELSE
        BEGIN
            PRINT ''Recovery mode of ? is already set to FULL''
        END
END'

There is one last thing to note about the above script, it used sp_executesql to alter the database, because if you execute the script below, you will get an ERROR on tempdb as contrairy to common sense, sp_msforeachdb becomes unstable when there is an ALTER DATABASE in the statement.

EXECUTE sp_msforeachdb '
IF ''?'' NOT IN(''master'',''msdb'',''tempdb'',''model'')
ALTER DATABASE [?] SET RECOVERY FULL'

Generates this error:

Msg 5058, Level 16, State 1, Line 3
Option ‘RECOVERY’ cannot be set in database ‘tempdb’.

Another great use of sp_msforeachdb is to set all of the database owners to the same owner – this becomes an issue when you just restored a bunch of databases and now YOU are the current owner.  In the case where you are logged in as a domain user and this is not your intended result – you need to current it immediately.

EXECUTE sp_msforeachdb 'USE [?]
IF (''?'' NOT IN(''master'',''msdb'',''tempdb'',''model''))
BEGIN
    DECLARE @currentOwner VARCHAR(50)
    DECLARE @newOwner VARCHAR(50) = ''sa''
    SELECT @currentOwner = suser_sname(owner_sid) from sys.databases where name = ''?''
    IF (@currentOwner != @newOwner)
        BEGIN
            EXECUTE sp_changedbowner @newOwner
            PRINT ''Updated owner of [?] to ['' + @newOwner + ''] (was set to ['' + @currentOwner + ''])''
        END
    ELSE
        BEGIN
            PRINT ''Owner of [?] is already set to ['' + @newOwner + '']''
        END
END'

AND one last great use of sp_msforeachdb  is to set the compatibility levels to the same value as such:

EXECUTE sp_msforeachdb '
IF (''?'' NOT IN(''master'',''msdb'',''tempdb'',''model''))
BEGIN
    DECLARE @currentCompatLevel TINYINT
    DECLARE @newCompatLevel TINYINT = 100
    SELECT @currentCompatLevel = compatibility_level from sys.databases where name = ''?''
    IF (@currentCompatLevel != @newCompatLevel)
        BEGIN
            DECLARE @cmdSql NVARCHAR(200) = N''ALTER DATABASE [?] SET COMPATIBILITY_LEVEL = '' + CONVERT(VARCHAR(5), @newCompatLevel)
            EXECUTE sp_executesql @cmdSql
            PRINT ''Updated compatibility level of [?] to ['' + CONVERT(VARCHAR(5), @newCompatLevel) + ''] (was set to ['' + CONVERT(VARCHAR(5),  @currentCompatLevel) + ''])''
        END
    ELSE
        BEGIN
            PRINT ''Compatibility level of [?] is already set to ['' + CONVERT(VARCHAR(5), @newCompatLevel) + '']''
        END
END'

Also – don’t forget about sp_msforeachdb’s little brother sp_msforeachtable which loops through all tables in a database.

Happy Looping…



Viewing all articles
Browse latest Browse all 10

Trending Articles