Query for backups - sql

I'm new to sql, and I'm trying to do a query for my backups, but I'm getting an error with some of the lines, I have 20 or more databases, but my query doesn't work on all the DB, its the same query for each DB, it display a message:
query:
USE [DB Name];
GO
BACKUP DATABASE DB Name
TO DISK = 'E:\xxxx\xx\DB Name.Bak'
;WITH FORMAT
MEDIANAME = 'DB Name_SQLServerBackups',
NAME = 'Full Backup DB Name'
Is giving the error message:
Msg 102, Level 15, State 1, Line 69
Incorrect syntax near 'DB Name'.
What am I doing wrong? Really appreciate your help.

Try using brackets around the second [DB Name] too and make a few syntax fixes to your command:
USE [DB Name];
GO
BACKUP DATABASE [DB Name]
TO DISK = 'E:\xxxx\xx\DB Name.Bak'
WITH FORMAT
, MEDIANAME = 'DB Name_SQLServerBackups'
, NAME = 'Full Backup DB Name';
(this worked for me)

Your best place to start would be with the scripts put together by Ola Hallengren which are very comprehensive and cover everything you will need.

Try this:
USE master
BACKUP DATABASE [AdventureWorks2012]
TO DISK = N'D:\Backup\AdventureWorks2012.bak'
WITH COPY_ONLY, NOFORMAT,
NOINIT,
NAME = N'AdventureWorks2012-Full Database Backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10
GO
--SPlit backup Process
USE master
BACKUP DATABASE [AdventureWorks2012]
TO DISK = N'D:\Backup\AdventureWorks2012_1.bak'
,DISK = N'D:\Backup\AdventureWorks2012_2.bak'
,DISK = N'D:\Backup\AdventureWorks2012_3.bak'
,DISK = N'D:\Backup\AdventureWorks2012_4.bak'
WITH COPY_ONLY, NOFORMAT,
NOINIT,
NAME = N'AdventureWorks2012-Full Database Backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10
GO

Here is a simple script that will backup all databases on your server. I would look carefully at this and learn exactly what it is doing. It's a good starting point but I would try to work to create your own scripts, what works best for you. The cursor allows you to iterate through all the databases and STATIC ensures you capture all databases when querying sys.databases.
/* Full database backup for all user databases. */
DECLARE #dbname varchar (300)
DECLARE #filepath varchar (1000)
DECLARE #filedate varchar (20)
DECLARE #filename varchar (256)
DECLARE #subdir varchar (1000)
SET #filepath = 'C:\TestBackup\' --This is your backup directory
SET #filedate = REPLACE(GETDATE(), ':', '_') --CONVERT(VARCHAR(10),GETDATE(),112) --gets the date and timestamp, replaces : with an underscore
DECLARE backup_cursor CURSOR STATIC FORWARD_ONLY FOR
SELECT [name]
FROM master.sys.databases sd
-- WHERE ... exclude databases
OPEN backup_cursor
FETCH NEXT FROM backup_cursor INTO #dbname
WHILE ##FETCH_STATUS = 0
BEGIN
SET #subdir = 'C:\Backup\' + #dbname
EXEC master.dbo.xp_create_subdir #subdir
SET #fileName = #filepath + #dbname + '\' + #dbname + '_' + #fileDate + '.bak'
BACKUP DATABASE #dbname TO DISK = #fileName
WITH CHECKSUM, STOP_ON_ERROR
RESTORE VERIFYONLY FROM DISK = #fileName
WITH STOP_ON_ERROR
FETCH NEXT FROM backup_cursor INTO #dbname
END
CLOSE backup_cursor
DEALLOCATE backup_cursor

Related

Backup script I've been using with no issues for a while tossing an error on new database

I've been using the code below to drop and create a new backup named (current year database)_daily at midnight to allow my team to test new scripts or updates to our student information system.
It worked all last year, and this year for reasons I can't figure out, the script is tossing an error.
Here is the script:
USE master;
GO
-- the original database (use 'SET #DB = NULL' to disable backup)
DECLARE #SourceDatabaseName varchar(200)
DECLARE #SourceDatabaseLogicalName varchar(200)
DECLARE #SourceDatabaseLogicalNameForLog varchar(200)
DECLARE #query varchar(2000)
DECLARE #DataFile varchar(2000)
DECLARE #LogFile varchar(2000)
DECLARE #BackupFile varchar(2000)
DECLARE #TargetDatabaseName varchar(200)
DECLARE #TargetDatbaseFolder varchar(2000)
-- ****************************************************************
SET #SourceDatabaseName = '[DST18000RD]' -- Name of the source database
SET #SourceDatabaseLogicalName = 'DST18000RD' -- Logical name of the DB ( check DB properties / Files tab )
SET #SourceDatabaseLogicalNameForLog = 'DST18000RD_log' -- Logical name of the DB ( check DB properties / Files tab )
SET #BackupFile = 'F:\Dev_Databases\Temp\backup.dat' -- FileName of the backup file
SET #TargetDatabaseName = 'DST18000RD_Daily' -- Name of the target database
SET #TargetDatbaseFolder = 'F:\Dev_Databases\Temp\'
-- ****************************************************************
SET #DataFile = #TargetDatbaseFolder + #TargetDatabaseName + '.mdf';
SET #LogFile = #TargetDatbaseFolder + #TargetDatabaseName + '.ldf';
-- Disconnect any users using #TargetDatabaseName
USE [master];
DECLARE #kill varchar(8000) = '';
SELECT #kill = #kill + 'kill ' + CONVERT(varchar(5), session_id) + ';'
FROM sys.dm_exec_sessions
WHERE database_id = db_id('DST18000RD_Daily')
EXEC(#kill);
-- Backup the #SourceDatabase to #BackupFile location
IF #SourceDatabaseName IS NOT NULL
BEGIN
SET #query = 'BACKUP DATABASE ' + #SourceDatabaseName + ' TO DISK = ' + QUOTENAME(#BackupFile,'''')
PRINT 'Executing query : ' + #query;
EXEC (#query)
END
PRINT 'OK!';
-- Drop #TargetDatabaseName if exists
IF EXISTS(SELECT * FROM sysdatabases WHERE name = #TargetDatabaseName)
BEGIN
SET #query = 'DROP DATABASE ' + #TargetDatabaseName
PRINT 'Executing query : ' + #query;
EXEC (#query)
END
PRINT 'OK!'
-- Restore database from #BackupFile into #DataFile and #LogFile
SET #query = 'RESTORE DATABASE ' + #TargetDatabaseName + ' FROM DISK = ' + QUOTENAME(#BackupFile,'''')
SET #query = #query + ' WITH MOVE ' + QUOTENAME(#SourceDatabaseLogicalName,'''') + ' TO ' + QUOTENAME(#DataFile ,'''')
SET #query = #query + ' , MOVE ' + QUOTENAME(#SourceDatabaseLogicalNameForLog,'''') + ' TO ' + QUOTENAME(#LogFile,'''')
PRINT 'Executing query : ' + #query
EXEC (#query)
PRINT 'OK!'
The script is not mine, I put together two scripts to get me what I needed. Our old database DST17000RD, this script still works flawlessly. On the new database DST18000RD, I get this error:
Executing query : BACKUP DATABASE [DST18000RD] TO DISK = 'F:\Dev_Databases\Temp\backup.dat'
Processed 1209552 pages for database 'DST18000RD', file 'DST18000RD' on file 23.
Processed 2 pages for database 'DST18000RD', file 'DST18000RD_log' on file 23.
BACKUP DATABASE successfully processed 1209554 pages in 139.942 seconds (67.525 MB/sec).
OK!
OK!
Executing query : RESTORE DATABASE DST18000RD_Daily FROM DISK = 'F:\Dev_Databases\Temp\backup.dat' WITH MOVE 'DST18000RD' TO 'F:\Dev_Databases\Temp\DST18000RD_Daily.mdf' , MOVE 'DST18000RD_log' TO 'F:\Dev_Databases\Temp\DST18000RD_Daily.ldf'
Msg 3234, Level 16, State 2, Line 3
Logical file 'DST18000RD' is not part of database 'DST18000RD_Daily'. Use RESTORE FILELISTONLY to list the logical file names.
Msg 3013, Level 16, State 1, Line 3
RESTORE DATABASE is terminating abnormally.
OK!
Some things to note that may just be me barking up the wrong tree. DST17000RD database is compatibility level SQL Server 2012 (110) and the DST18000RD database is SQL Server 2017 (140). The server was upgraded and migrated a couple months ago before the new database was created.
Any help is appreciated. From what I can tell, I feel like the script is not renaming the MDF and LDF files before it tries to copy them for the *_daily database? Honestly I'm not sure. I'm a pretend DBA, self taught on an as needed basis. Thank you in advance for your help!
The error is telling you got the logical name of the db file wrong:
SET #SourceDatabaseLogicalName = 'DST18000RD' -- Logical name of the DB ( check DB properties / Files tab )
and to run:
RESTORE FILELIST ONLY FROM DISK = 'F:\Dev_Databases\Temp\backup.dat'
To see the correct logical file names.
The issue is you are trying to change the file logical name during the database restore, which is not possible even if you use the MOVE clause.
The MOVE clause allows you to change the location and the names of the physical files but does not do anything for the logical names.
Fix
You will have to use the existing logical names for your database, but once you have restored the database then use ALTER DATABASE command to change the logical names of your files using the following command:
USE [master];
GO
ALTER DATABASE [DST18000RD]
MODIFY FILE ( NAME = DST17000RD , NEWNAME = DST18000RD );
GO

SQL GO disrupts chain of local variables

I use script for DB backup as below:
---- INITIALIZATION
-- UNIFIED DATE
DECLARE #DAT DATETIME
SELECT #DAT = GETDATE()
-- DEFAULT BACKUPS LOCATION
DECLARE #PATH VARCHAR(20)
SELECT #PATH = 'Q:\DBbackup\Default\'
---- DATABASE BACKUPS
-- DB1
DECLARE #DBNAME VARCHAR(64)
SELECT #DBNAME = 'DB1'
DECLARE #BACKUPNAME VARCHAR(64)
DECLARE #DESCRIPTION VARCHAR (255)
SELECT #BACKUPNAME = (#PATH + #DBNAME +'_'+ CONVERT(VARCHAR(19),#DAT,121) + '.bak')
SELECT #DESCRIPTION = #DBNAME + ' Full ad hoc backup ' + CONVERT(VARCHAR(20),#DAT)
SELECT #BACKUPNAME
BACKUP DATABASE #DBNAME TO DISK = #BACKUPNAME WITH FORMAT, INIT, NAME = #DESCRIPTION, SKIP, NOREWIND, NOUNLOAD, STATS = 10, COMPRESSION
GO
-- DB2
DECLARE #DBNAME VARCHAR(64)
SELECT #DBNAME = 'DB2'
DECLARE #BACKUPNAME VARCHAR(64)
DECLARE #DESCRIPTION VARCHAR (255)
SELECT #BACKUPNAME = (#PATH + #DBNAME + '_' + CONVERT(VARCHAR(19),#DAT,121) + '.bak')
SELECT #DESCRIPTION = #DBNAME + ' Full ad hoc backup ' + CONVERT(VARCHAR(20),#DAT)
BACKUP DATABASE #DBNAME TO DISK = #BACKUPNAME WITH FORMAT, INIT, NAME = #DESCRIPTION, SKIP, NOREWIND, NOUNLOAD, STATS = 10, COMPRESSION
GO
However, for backup DB2 the variables #PATH and #DAT are not found as they apply only to first backup. It seems the GO command cancels the effect of local variables for DB2 backup. Is there any workaround for this situation? I want to use the variables in INIT only once, not duplicate them for each database backup.
SQL Server does not know what GO means. That's an SSMS feature. It causes multiple batches to be sent. Either remove GO (and restructure the variables so that they are declared only once) or store that data in a persistent location such as a temp table.
Unfortunately, no great options. T-SQL is a stone-age language.

full backups occasionally skipping certain databases

We have a job set up to run a script every night to do a full backup on all of our databases. Recently, we noticed that sometimes the last two databases are skipped, but not all of the time. We have a tracking table that we are inserting the state of each database in when we do the backups. On the nights that the last two databases are skipped, the state for those databases doesn't get recorded in the tracking table either. We can't figure out why those databases are being skipped. This is the backup script we are using:
DECLARE #dbname VARCHAR(100),
#dbid INT,
#rcmodel VARCHAR(50),
#state VARCHAR(60),
#date VARCHAR(50),
#time VARCHAR(50),
#sql VARCHAR(3000),
#dir VARCHAR(1000),
#path VARCHAR(100),
#type VARCHAR(10)
SET #path = 'E:\Backups\'
SET #type = 'Full'
SET #date = REPLACE(CONVERT(date,GETDATE(),101),'-','_')
SET #time = REPLACE(CONVERT(TIME(0), GETDATE()),':','_')
SET #path = #path + CONVERT(VARCHAR(30),##SERVERNAME) + '\' + #type + '\'
DECLARE BackupCur CURSOR FOR
SELECT NAME, database_id, recovery_model_desc, state_desc
FROM sys.databases
WHERE NAME <> 'tempdb'
OPEN BackupCur
FETCH NEXT FROM BackupCur INTO #dbname, #dbid, #rcmodel, #state
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO backuptrackingtable (db, statedesc, datecreated)
values (#dbname, #state, GETDATE())
IF #type = 'Full' AND #state = 'ONLINE'
BEGIN
SET #dir = 'EXECUTE master.dbo.xp_create_subdir N'''+#path+#dbname+''''
SET #sql = 'BACKUP DATABASE '+#dbname+' TO DISK = N'''+#path+#dbname+'\'+#dbname+'_'+#date+'.bak'' WITH NOFORMAT, INIT, SKIP, REWIND, NOUNLOAD, COMPRESSION'
PRINT 'Backing up ' + #dbname
EXEC (#dir)
EXEC (#sql)
END
IF #type = 'Log' AND #dbid > 4 AND #rcmodel = 'FULL' AND #state = 'ONLINE'
BEGIN
SET #dir = 'EXECUTE master.dbo.xp_create_subdir N'''+#path+#dbname+''''
SET #sql = 'BACKUP LOG '+#dbname+' TO DISK = N'''+#path+#dbname+'\'+#dbname+'_'+#date+'__'+#time+'.bak'' WITH NOFORMAT, INIT, SKIP, REWIND, NOUNLOAD, COMPRESSION'
PRINT 'Backing up ' + #dbname
EXEC (#dir)
EXEC (#sql)
END
FETCH NEXT FROM BackupCur INTO #dbname, #dbid, #rcmodel, #state
END
CLOSE BackupCur
DEALLOCATE BackupCur
Can think of three possible explanations.
They aren't being returned from the query against sys.databases because they don't exist or the user running the query doesn't have permissions on them.
An unhandled error means that the script aborts before processing them.
##FETCH_STATUS returns -2 at some point because a database has been dropped since the keyset cursor opened.
You would need to put more logging in to investigate further. But you might want to consider using a maintenance plan (dependant on edition) or Ola Hallengren's DB maintenance scripts rather than re-inventing the wheel anyway.

how to pass all database (fast) since sql server 2008 express to sql server 2008 R2 (NO express)

well i had sql 2008 express, and now i have installed, sql server, now i want to delete sql express, but in that instance i have all my database i have worked (plus of 20), so they are very important for me, how can i pass it to sql server 2008 r2, i know i can do database of all but i dont want to work a lot of, there is a way short, for to pass al database? coping a folder? something? thanks!
I Attached all database, and i added, all (but one for one) i added all in the same windows and in 5 minutos i had all database in sql (no express)
Create an SSIS package with 4 steps.
First, a Execute SQL task that backups all DBs to a specific location:
exec sp_msforeachdb '
IF DB_ID(''?'') > 4
Begin
BACKUP DATABASE [?] TO DISK = N''\\Backups\?.BAK'' WITH NOFORMAT, INIT,
NAME = N''?-Full Database Backup'', SKIP, NOREWIND, NOUNLOAD
declare #backupSetId as int
select #backupSetId = position from msdb..backupset where database_name=N''?''
and backup_set_id=(select max(backup_set_id) from msdb..backupset
where database_name=N''?'' )
if #backupSetId is null begin
raiserror(N''Verify failed. Backup information for database ''''?'''' not found.'', 16, 1)
end
RESTORE VERIFYONLY FROM DISK = N''\\Backups\?.BAK'' WITH
FILE = #backupSetId, NOUNLOAD, NOREWIND
End
'
Second, Create a SP to restore DBs using a variable for location and DB name:
CreatePROCEDURE [dbo].[uSPMas_RestoreDB] #DBname NVARCHAR(200),
#BackupLocation NVARCHAR(2000)
AS
BEGIN
SET nocount ON;
create table #fileListTable
(
LogicalName nvarchar(128),
PhysicalName nvarchar(260),
[Type] char(1),
FileGroupName nvarchar(128),
Size numeric(20,0),
MaxSize numeric(20,0),
)
insert into #fileListTable EXEC('RESTORE FILELISTONLY FROM DISK = '''+#BackupLocation+#dbname+'.bak''')
Declare #Dname varchar(500)
Set #Dname = (select logicalname from #fileListTable where type = 'D')
Declare #LName varchar(500)
Set #LName = (select logicalname from #fileListTable where type = 'L')
declare #sql nvarchar(4000)
SET #SQL = 'RESTORE DATABASE ['+ #dbname +'] FROM
DISK = N'''+#BackupLocation + #dbname +'.BAK'' WITH FILE = 1,
MOVE N'''+ #Dname +''' TO N''E:\YourLocation\'+ #dbname +'.mdf'',
MOVE N'''+ #LName +''' TO N''D:\Your2ndLocation\'+ #dbname +'_log.ldf'',
NOUNLOAD, REPLACE, STATS = 10'
exec sp_executesql #SQL
drop table #fileListTable
END
Third, Create a ForEach Loop Container and put a Execute Sql Statement with variable:
EXEC uSPMas_RestoreDB ? , ?
Use the for ForEach Loop Container to pass the variables
Fourth, Create a 'Transfer Logins' task to move over all DB logins

How to build a script to backup all databases in SQL Server?

We need to backup 40 databases inside a SQL Server instance. We backup each database with the following script:
BACKUP DATABASE [dbname1] TO DISK = N'J:\SQLBACKUPS\dbname1.bak' WITH NOFORMAT, INIT, NAME = N'dbname1-Full Database Backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10
GO
declare #backupSetId as int
select #backupSetId = position from msdb..backupset where database_name=N'dbname1' and backup_set_id=(select max(backup_set_id) from msdb..backupset where database_name=N'dbname1' )
if #backupSetId is null begin raiserror(N'Verify failed. Backup information for database ''dbname1'' not found.', 16, 1) end
RESTORE VERIFYONLY FROM DISK = N'J:\SQLBACKUPS\dbname1.bak' WITH FILE = #backupSetId, NOUNLOAD, NOREWIND
GO
We will like to add to the script the functionality of taking each database and replacing it in the above script. Basically a script that will create and verify each database backup from an engine.
I am looking for something like this:
For each database in database-list
sp_backup(database) // this is the call to the script above.
End For
any ideas?
Use SqlBackupAndFTP. Select "Backup all non-system databases"
Maybe you can check the sp_MSForEachDB stored procedure.
EXEC sp_MSForEachDB 'EXEC sp_backup ?'
Where the ? mark stands for the current database on each iteration.
You said "verify" too... This would require a 2nd statement per database (RESTORE VERIFYONLY, as well the other answers offered.
I'd investigate using maintenance plans to include index maintenance too...
Something like:
DECLARE #SQL varchar(max)
SET #SQL = ''
SELECT #SQL = #SQL + 'BACKUP ' + Name + ' To Disk=''c:\' + Name + '.bak'';'
FROM sys.sysdatabases
EXEC(#SQL)
SQL Backup Master has the ability to back up all databases on a given server instance and then send the backups to Dropbox, FTP, Amazon S3, Google Drive, or local/network folder.