Tara Kizer Blog

Tara Kizer

Backup databases stored procedure - new version

EDIT: Please see my new version of this stored procedure.

I've been asked a few times if there was a way to change the number of days to retain the backup files for in my backup stored procedure.  Due to this, I have modified the sproc so that you can now input the number of days to retain the files for.  Here is the updated version:

----------------------------------------------------------------------------------------------------
-- OBJECT NAME         : isp_Backup
--
-- AUTHOR               : Tara Duggan
-- DATE     : December 18, 2003
--
-- INPUTS    : @Path - location of the backups
--        @dbType - which databases to backup - All, System, or User
--        @Retention - numbers of days to retain backups
-- OUTPUTS    : None
-- DEPENDENCIES         : None
--
-- DESCRIPTION         : This stored procedure performs a full backup on all of the user databases
--
-- EXAMPLES (optional)  : EXEC isp_Backup @Path = 'E:\MSSQL\Backup\', @dbType = 'All', @Retention = 5
----------------------------------------------------------------------------------------------------
CREATE            PROC isp_Backup
(@Path VARCHAR(100), @dbType VARCHAR(6), @Retention INT = 2)
AS

SET NOCOUNT ON

DECLARE @Now CHAR(14) -- current date in the form of yyyymmddhhmmss
DECLARE @DBName SYSNAME -- stores the database name that is currently being processed
DECLARE @cmd SYSNAME -- stores the dynamically created DOS command
DECLARE @Result INT -- stores the result of the dir DOS command
DECLARE @RowCnt INT -- stores @@ROWCOUNT
DECLARE @filename VARCHAR(200) -- stores the path and file name of the BAK file

CREATE TABLE #WhichDatabase
(
 dbName SYSNAME NOT NULL
)

-- Get the list of the databases to be backed up
IF @dbType = 'All'

 INSERT INTO #WhichDatabase (dbName)
 SELECT [name]
 FROM master.dbo.sysdatabases
 WHERE [name] <> 'tempdb' AND
    [name] NOT IN (SELECT database_name FROM msdb.dbo.log_shipping_databases)
 ORDER BY [name]

ELSE
BEGIN

 IF @dbType = 'System'

  INSERT INTO #WhichDatabase (dbName)
  SELECT [name]
  FROM master.dbo.sysdatabases
  WHERE [name] IN ('master', 'model', 'msdb')
  ORDER BY [name]

 ELSE
 BEGIN

  IF @dbType = 'User'

   INSERT INTO #WhichDatabase (dbName)
   SELECT [name]
   FROM master.dbo.sysdatabases
   WHERE [name] NOT IN ('master', 'model', 'msdb', 'tempdb') AND
      [name] NOT IN (SELECT database_name FROM msdb.dbo.log_shipping_databases)
   ORDER BY [name]

  ELSE
  BEGIN

   DROP TABLE #WhichDatabase

   RETURN -1

  END

 END

END

-- Get the database to be backed up
SELECT TOP 1 @DBName = dbName
FROM #WhichDatabase

SET @RowCnt = @@ROWCOUNT

-- Iterate throught the temp table until no more databases need to be backed up
WHILE @RowCnt <> 0
BEGIN

 -- Get the current date using style 120, remove all dashes, spaces, and colons
 SELECT @Now = REPLACE(REPLACE(REPLACE(CONVERT(VARCHAR(50), GETDATE(), 120), '-', ''), ' ', ''), ':', '')

 -- Build the .BAK path and file name
 SELECT @filename = @Path + @DBName + '\' + @DBName + '_' + @Now + '.BAK'
 
 -- Build the dir command that will check to see if the directory exists
 SELECT @cmd = 'dir ' + @Path + @DBName

 -- Run the dir command, put output of xp_cmdshell into @result
 EXEC @result = master.dbo.xp_cmdshell @cmd, NO_OUTPUT

 -- If the directory does not exist, we must create it
 IF @result <> 0
 BEGIN
  
  -- Build the mkdir command  
  SELECT @cmd = 'mkdir ' + @Path + @DBName

  -- Create the directory
  EXEC master.dbo.xp_cmdshell @cmd, NO_OUTPUT

 END
 -- The directory exists, so let's delete files older than two days
 ELSE
 BEGIN

  -- Stores the name of the file to be deleted
  DECLARE @WhichFile VARCHAR(1000)

  CREATE TABLE #DeleteOldFiles
  (
   DirInfo VARCHAR(7000)
  )

  -- Build the command that will list out all of the files in a directory
  SELECT @cmd = 'dir ' + @Path + @DBName + ' /OD'

  -- Run the dir command and put the results into a temp table
  INSERT INTO #DeleteOldFiles
  EXEC master.dbo.xp_cmdshell @cmd

  -- Delete all rows from the temp table except the ones that correspond to the files to be deleted
  DELETE
  FROM #DeleteOldFiles
  WHERE ISDATE(SUBSTRING(DirInfo, 1, 10)) = 0 OR DirInfo LIKE '%

%' OR SUBSTRING(DirInfo, 1, 10) >= GETDATE() - @Retention

 

  -- Get the file name portion of the row that corresponds to the file to be deleted
  SELECT TOP 1 @WhichFile = SUBSTRING(DirInfo, LEN(DirInfo) -  PATINDEX('% %', REVERSE(DirInfo)) + 2, LEN(DirInfo))
  FROM #DeleteOldFiles

  
  SET @RowCnt = @@ROWCOUNT
  
  -- Interate through the temp table until there are no more files to delete
  WHILE @RowCnt <> 0
  BEGIN
  
   -- Build the del command
   SELECT @cmd = 'del ' + @Path + + @DBName + '\' + @WhichFile + ' /Q /F'
   
   -- Delete the file
   EXEC master.dbo.xp_cmdshell @cmd, NO_OUTPUT
   
   -- To move to the next file, the current file name needs to be deleted from the temp table
   DELETE
   FROM #DeleteOldFiles
   WHERE SUBSTRING(DirInfo, LEN(DirInfo) -  PATINDEX('% %', REVERSE(DirInfo)) + 2, LEN(DirInfo))  = @WhichFile

   -- Get the file name portion of the row that corresponds to the file to be deleted
   SELECT TOP 1 @WhichFile = SUBSTRING(DirInfo, LEN(DirInfo) -  PATINDEX('% %', REVERSE(DirInfo)) + 2, LEN(DirInfo))
   FROM #DeleteOldFiles
  
   SET @RowCnt = @@ROWCOUNT
  
  END
  
  DROP TABLE #DeleteOldFiles

 END

 -- Backup the database
 BACKUP DATABASE @DBName
 TO DISK = @filename
 WITH INIT

 -- To move onto the next database, the current database name needs to be deleted from the temp table
 DELETE
 FROM #WhichDatabase
 WHERE dbName = @DBName

 -- Get the database to be backed up
 SELECT TOP 1 @DBName = dbName
 FROM #WhichDatabase

 SET @RowCnt = @@ROWCOUNT
 
 -- Let the system rest for 5 seconds before starting on the next backup
 WAITFOR DELAY '00:00:05'

END

DROP TABLE #WhichDatabase

SET NOCOUNT OFF

RETURN 0

 


I will also post the updated LS and transaction log sprocs as well.

 

BTW, this sproc is designed for SQL Server 2000 Enterprise Edition only.  For Standard Edition, change this:

 INSERT INTO #WhichDatabase (dbName)
 SELECT [name]
 FROM master.dbo.sysdatabases
 WHERE [name] <> 'tempdb' AND
    [name] NOT IN (SELECT database_name FROM msdb.dbo.log_shipping_databases)
 ORDER BY [name]

to:

 INSERT INTO #WhichDatabase (dbName)
 SELECT [name]
 FROM master.dbo.sysdatabases
 WHERE [name] <> 'tempdb'
 ORDER BY [name]

Legacy Comments


Gary
2004-08-10
re: Backup databases stored procedure - new version
Thanks very much for a very informative website, it nice that you take some time out to help aspiring DBA's :) Looking forward to your transaction log & LS sprocs.

Best Regards

Gary

Ivan
2004-08-19
re: Backup databases stored procedure - new version
Hi,

Sorry for the stupid question, but I having troubles trying to backup the database to a remote (network shared driver)

This is how I run it:
EXEC isp_Backup @Path = 'Z:\BACKUP\MTA_SQLTEST_BACKUP', @dbType = 'User', @Retention = 5

And this is the result:
Server: Msg 3201, Level 16, State 1, Procedure isp_Backup, Line 175
Cannot open backup device 'Z:\BACKUP\MTA_SQLTEST_BACKUPEQUOTE\EQUOTE_20040819101027.BAK'. Device error or device off-line. See the SQL Server error log for more details.
Server: Msg 3013, Level 16, State 1, Procedure isp_Backup, Line 175
BACKUP DATABASE is terminating abnormally.
Server: Msg 3201, Level 16, State 1, Procedure isp_Backup, Line 175
Cannot open backup device 'Z:\BACKUP\MTA_SQLTEST_BACKUPMTA_TEST\MTA_TEST_20040819101033.BAK'. Device error or device off-line. See the SQL Server error log for more details.
Server: Msg 3013, Level 16, State 1, Procedure isp_Backup, Line 175
BACKUP DATABASE is terminating abnormally.

Thanks

Ivan
2004-08-19
Never mind guys...I found the problem
I changed the command to

This is how I run it:
EXEC isp_Backup @Path = '\\SERVER\BACKUP\MTA_SQLTEST_BACKUP', @dbType = 'User', @Retention = 5

and it is working now

Thanks

Gordon Withers
2004-09-04
re: Backup databases stored procedure - new version

Thanks for the wonderful stored procedure -- it is a godsend for jumpstarting my two-week-old database and application development career (former web designer with no comprehension of the back end of things).

Gordon

Jeet
2004-09-24
re: Backup databases stored procedure - new version
Tara:

Great site with great info.

I modified the SP isp_Backup, to add support for single database backup. This change will help to take backup for single database also. Thanks again for the script.


-- Get the list of the databases to be backed up
IF @dbType = 'All'
INSERT INTO #WhichDatabase (dbName)
SELECT [name]
FROM master.dbo.sysdatabases
WHERE [name] <> 'tempdb'
AND [name] NOT IN (SELECT database_name FROM msdb.dbo.log_shipping_databases)
ORDER BY [name]
ELSE
BEGIN
IF @dbType = 'System'
INSERT INTO #WhichDatabase (dbName)
SELECT [name]
FROM master.dbo.sysdatabases
WHERE [name] IN ('master', 'model', 'msdb')
ORDER BY [name]
ELSE
BEGIN
IF @dbType = 'User'
INSERT INTO #WhichDatabase (dbName)
SELECT [name]
FROM master.dbo.sysdatabases
WHERE [name] NOT IN ('master', 'model', 'msdb', 'tempdb')
AND [name] NOT IN (SELECT database_name FROM msdb.dbo.log_shipping_databases)
ORDER BY [name]
ELSE
BEGIN
IF @dbType != ''
IF EXISTS (SELECT [name] FROM master.dbo.sysdatabases WHERE [name] = @dbType)
INSERT INTO #WhichDatabase (dbName)
SELECT @dbType
ELSE
BEGIN
DROP TABLE #WhichDatabase
RETURN -1
END
ELSE
BEGIN
DROP TABLE #WhichDatabase
RETURN -1
END
END
END
END

hassan mir
2005-07-06
re: Backup databases stored procedure - new version
I have wierd problem,, when i run this script to backup onto a network share -- it locks up that machine and the backup fails with this error

BackupDiskFile::ReruestDurableMedia: failure on backup device '\\fs-arc\ndb\srlbackup\nightlyBackup\arc\arc_20050706144259.BAK'. Operating system error 64(The specified network name is no longer available.).

as soon as i kill the job, fs-arc machine is back to normal ,, this machine is a network file server and shows no problem with anythign else,, just the backup,, i tried to define a manitainace plan but got the same error

any ideas? i am at loss

thanks

Tara
2005-07-06
re: Backup databases stored procedure - new version
You are probably running into a permission or network problem which is outside of the scope of this stored procedure.

I do not recommend backing up directly to a network share. Backup the database to the local disk using this stored procedure. Then use xcopy to move the backup file to the network share. Your backups will be more reliable if you use this method.


hassan mir
2005-07-06
re: Backup databases stored procedure - new version
one more thing, i tried to do the backup on local disk and then to a different network share (ohter than the machine that is causing the problem) ,, both worked just fine. thanks

hassan mir
2005-07-06
re: Backup databases stored procedure - new version
how do i use XCOPY from within the script,, so i can copy it to local disk and at the end of it XCOPY it to network share,, thanks

Tara
2005-07-06
re: Backup databases stored procedure - new version
You wouldn't do this within the same script. Just add another step to your job. This second step would use CmdExec to execute xcopy. Run xcopy /? from a cmd window to see its options.

Jim Hughes
2005-08-31
re: Backup databases stored procedure - new version
Script needs to be updated to support use on a Case Sensitive installation of SQL server.

@Result needs to be consistently used (somtimes @result and sometimes @Result) and sysname needs to be lowercase..

Dmitrey
2005-09-15
re: Backup databases stored procedure - new version
Hi thanks for your, sp works well. The only thing I had to do is change it a little to work on the system with British date format dd/mm/yyyy. Thanks again.

Your Code
-------
DELETE
FROM #DeleteOldFiles
WHERE SUBSTRING(DirInfo, LEN(DirInfo) - PATINDEX('% %', REVERSE(DirInfo)) + 2, LEN(DirInfo)) = @WhichFile
-------
Your Code End

to

Change Code Start
-------
DELETE FROM #DeleteOldFiles WHERE SUBSTRING(DirInfo, 3, 1) <> '/' OR ISNULL(DirInfo, '') = ''

DELETE
FROM #DeleteOldFiles
WHERE ISDATE(CONVERT(DATETIME, SUBSTRING(DirInfo, 1, 10), 103)) = 0 OR CONVERT(DATETIME, SUBSTRING(DirInfo, 1, 10), 103) >= GETDATE() - @Retention
-------
Change Code End

girish
2005-10-13
re: Backup databases stored procedure - new version
Hi,
I need a sp which give me result for a specified database not for all database on server.

Regards
Girish

girish
2005-10-14
re: Backup databases stored procedure - new version
Error Type:
Microsoft OLE DB Provider for SQL Server (0x80040E09)
EXECUTE permission denied on object 'xp_cmdshell', database 'master', owner 'dbo'.

Tara
2005-10-14
re: Backup databases stored procedure - new version
My stored procedures are designed from the perspective of a sysadmin. Since you got a permission denied error on xp_cmdshell, then you must not be a member of that role. My stored procedures are not designed for one individual database, but they certainly can be rewritten easily.

Himansu
2005-12-12
re: Backup databases stored procedure - new version
Thanks for the cod. But it wouldn't work when running the stored proc in remote server and trying to take backup in the local machine.

Any solution is highly appreciable.

Thanks in advance.

Tara
2005-12-15
re: Backup databases stored procedure - new version
Himansu,

You'll need to explain what you tried. The stored procedure is designed to run locally on the database server that you wish to backup. It can accept a network path as the location for the backups to be saved to. But it must be run locally. Running it remotely is not supported by my code.

mirel
2006-05-18
re: Backup databases stored procedure - new version
The prcedure does not work when backing up single database, and name of database contains "-"

mirel
2006-05-18
re: Backup databases stored procedure - new version
UPS SORRY,MY MISTAKE
ARGUMENT SIZE @dbType VARCHAR(6) IS TO SMALL

WHEN I REPLACE WITH THIS
@dbType VARCHAR(100) PROCEDURE WORK




Tara
2006-05-18
re: Backup databases stored procedure - new version
mirel, what are you passing into @dbType that requires a length greater than 6? The stored procedure does not support anything greater than 6, so I'm not sure what you are trying to do.

hrudhay
2006-06-15
re: Backup databases stored procedure - new version
Create Procedure BackupDatabase
(
@ID int OUTPUT
)
@Database Varchar(100),
@BackupDir Varchar(500)
As
If Right(@BackupDir,1)='\'
Set @BackupDir=@BackupDir + @Database +
(SELECT REPLACE(REPLACE(REPLACE(CONVERT(VARCHAR(50), GETDATE(), 120), '-', ''), ' ', ''), ':', ''))+'.Bak'
Else
Set @BackupDir =@BackupDir + '\' + @Database + (SELECT REPLACE(REPLACE(REPLACE(CONVERT(VARCHAR(50), GETDATE(), 120), '-', ''), ' ', ''), ':', ''))+'.Bak'
Backup Database @Database
To Disk =@Backupdir
With STATs =10



How to get results for sucess and failure for above sp

Joe
2006-07-13
re: Backup databases stored procedure - new version
Hi all.

I tried to run the modified Jeet's version, for a single database, and it backup nothing ... any ideas?... i recieved no error, but it does not backup either ..

Igor
2006-08-16
Databases with space on the name
Tara/All -
Just an FYI,
I loved the sp, however, there's only one small issue, the sp fails to back up the databases with spaces on the database name (i.e. 'Customer Database'). Unusual to all of us, but I thought you might want to know that.

Thanks!

igor

John Burns
2006-10-11
re: Backup databases stored procedure - new version
I have this running on one server and it works great. I just set up a new SQL 2000 server and tried running it and I'm getting an error. It tells me the table msdb.dbo.log_shipping_databases doesn't exist, and it doesn't. Did I miss something during my installation? I'm not doing log shipping or anything special, just a standard SQL 2000 Server install. Any suggestions? Am I missing something stupid?

Tara
2006-10-11
re: Backup databases stored procedure - new version
John, comment that part out of the code. I wrote it for Enterprise Edition which supports log shipping. Standard Edition does not.


2006-11-10
re: Backup databases stored procedure - new version
good