Management Studio Diffrent files after backup - sql-server

I have database in SQL Server Managment Studio. I make a backup of my database using this script:
use mydatabase
BACKUP DATABASE mydatabase
TO DISK = 'D:\mydatabase\backup.BAK'
GO
BACKUP DATABASE mydatabase
TO DISK = 'E:\mydatabase\work.BAK'
GO
My problem is that the files backup.BAK and work.BAK have the same size. I check every byte and this files are not the same. Did anyone know why?

Depending on the size of your database, it may take a while to generate the backup. Depending on the activity, a lot can change in the database during this time. To create exact copies of your backup file, you should just copy the first backup file. You can do this in SQL, for example:
DECLARE #SourceFile AS VARCHAR(500);
DECLARE #DestinationFile AS VARCHAR(500);
DECLARE #Cmd AS VARCHAR(500);
BACKUP DATABASE mydatabase
TO DISK = 'D:\mydatabase\backup.BAK'
GO
SET #SourceFile = 'D:\mydatabase\backup.BAK'
SET #DestinationFile = 'E:\mydatabase\work.BAK'
SET #Cmd = 'COPY ' + #SourceFile + ' ' + #DestinationFile;
EXEC master.dbo.xp_cmdshell #Cmd;

Related

SQL Server 2014 Create a Copy of an Existing Database

I've been trying to make a copy of a SQL Server Database (2014) and the recommended way to do this using SQL Server Management Studio seems to be the following.
Right Click Database >
Tasks >
Generate Scripts >
Advanced (Schema and Data) (Single file per object)
Then I have to update the references to the database name to use the new database name.
This won't work for me though because some of the object files it outputs can be over a GB which means I can't open the file to change the database name.
Is there another way to create a copy of a database to a new database with a different name?
I use this script for that.
declare #nameSuffix varchar(50) = 'DB_NEW_NAME'
declare #path varchar(250) = 'C:\Program Files\Microsoft SQL Server\YOUR PATH\MSSQL\'
declare #backupfile varchar(250) = #path + 'Backup\' + #nameSuffix + '.bak'
declare #moveFile varchar(300) = #path + 'DATA\' + #nameSuffix + '.mdf'
declare #moveLogFile varchar(300) = #path + 'DATA\' + #nameSuffix + '_log.ldf'
backup database DB1
to disk = #backupfile
with init, noformat, skip, stats=10
use master
restore database DB_NEW_NAME
from disk = #backupfile
with replace,
recovery,
move 'DB1' to #moveFile,
move 'DB1_Log' to #moveLogFile
you can copy the database by:
right click database to be copied > tasks > copy database
the database wizard will guide you to create your new copy.
more resources here: https://msdn.microsoft.com/en-us/library/ms188664.aspx

How can I copy an entire database to another on the same server?

I want to copy a database A into database B (same SQL Server) entirely - what would be the easiest SQL or utility command to do that? (database B should be 100% erased before the copy)
Note that it can be non-SQL thing, but in any case I need to run it as one-click. So some utility that does that is also acceptable as far as I can run copying with one click or from command line.
SQL Server 2008R2 or 2012.
Best, Askar
I made a soultion based on David's thoughts. It looks like this (Prod - source DB, Demo - destination copy)
DECLARE #backup varchar(300) = 'e:\Prod.bak';
DECLARE #logic_db_file varchar(300) = 'koe';
DECLARE #logic_log_file varchar(300) = 'koe_log';
DECLARE #out_db_file varchar(300) = 'c:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\Demo.mdf';
DECLARE #out_log_file varchar(300) = 'c:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\Demo_log.ldf';
PRINT N'Backing up Production database.'
BACKUP DATABASE Prod
TO DISK = #backup WITH FORMAT;
PRINT N'Restoring FILELISTONLY, see log file for data.'
-- Restore the files to Demo
RESTORE FILELISTONLY
FROM DISK = #backup
PRINT N'Getting exclusive access to Demo'
Alter database Demo set single_user with rollback immediate
drop database Demo
PRINT N'Restoring backup to Test database'
RESTORE DATABASE Demo
FROM DISK = #backup
WITH REPLACE,
MOVE #logic_db_file TO #out_db_file,
MOVE #logic_log_file TO #out_log_file
GO
-- if you want you can do some SQL fixes to newly made DB
PRINT N'Changing normal users to demo users, if account type is OK'
USE Demo;
UPDATE USER_ACCOUNTS SET ACCOUNT_TYPE=3 WHERE (STATUS=1) AND (ACCOUNT_TYPE=1);
GO

How to rename the Physical Database Files

I have used tsql to detach a database like this:
EXEC sp_detach_db #dbname = 'my_db'
I then made use of PHP to rename the physical files. I was able to rename the mdf file but not the ldf file! I even tried a dos command REN but that didn't work for the ldf file either!
I wanted to ask, is there something special about the physical log files that allow it not to be renamed?
Is there a better way of doing this?
Thanks all
Detach the Database, Rename the files, Attach it again.
Backup the original database
Drop the original database
Restore the original database from the backup, but with different name; the files of the restored database will be also automatically named taking into account new database name.
The "ALTER DATABASE (your database) MODIFY FILE" command will only rename the logical names. This post shows how to use xp_cmdshell to also rename the physical files: http://www.mssqltips.com/sqlservertip/1891/best-practice-for-renaming-a-sql-server-database/
Please note the following:
1. xp_cmdshell will be executed under the user which the SQL Server process runs as, and might not have the file system permissions required to rename the database files
2. For security reasons, remember to disable xp_xmdshell
The following is an example of how the renaming can be done based on the mentioned blog post. It will replace the database MyDB with the database NewMyDB. The original MyDB (renamed to MyDB_OLD) will be left detached.
-- Enable xp_cmdshell:
sp_configure 'show advanced options', 1
RECONFIGURE WITH OVERRIDE
GO
sp_configure 'xp_cmdshell', 1
RECONFIGURE WITH OVERRIDE
GO
-- Get physical file names:
declare #MyDBOriginalFileName nvarchar(300) = (select physical_name FROM sys.master_files where name = 'MyDB')
declare #MyDBLogOriginalFileName nvarchar(300) = (select physical_name FROM sys.master_files where name = 'MyDB_log')
declare #NewMyDBOriginalFileName nvarchar(300) = (select physical_name FROM sys.master_files where name = 'NewMyDB')
declare #NewMyDBLogOriginalFileName nvarchar(300) = (select physical_name FROM sys.master_files where name = 'NewMyDB_log')
declare #Command nvarchar(500)
declare #Sql nvarchar(2000)
IF (EXISTS (select * from sys.databases where name = 'NewMyDB')
AND EXISTS (select * from sys.databases where name = 'MyDB'))
BEGIN
USE master
ALTER DATABASE MyDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE
ALTER DATABASE NewMyDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE
-- Set new database name
ALTER DATABASE MyDB MODIFY NAME = MyDB_OLD
ALTER DATABASE NewMyDB MODIFY NAME = MyDB
-- Update logical names
ALTER DATABASE MyDB_OLD MODIFY FILE (NAME=N'MyDB', NEWNAME=N'MyDB_OLD')
ALTER DATABASE [MyDB] MODIFY FILE (NAME=N'NewMyDB', NEWNAME=N'MyDB')
EXEC master.dbo.sp_detach_db #dbname = N'MyDB_Old'
EXEC master.dbo.sp_detach_db #dbname = N'MyDB'
-- Rename physical files
SET #Command = 'RENAME "' + #MyDBOriginalFileName + '" "MyDB_OLD.mdf"'; PRINT #Command
EXEC xp_cmdshell #Command
SET #Command = 'RENAME "' + #MyDBLogOriginalFileName + '" "MyDB_OLD_log.mdf"'; PRINT #Command
EXEC xp_cmdshell #Command
SET #Command = 'RENAME "' + #NewMyDBOriginalFileName + '" "MyDB.mdf"'; PRINT #Command
EXEC xp_cmdshell #Command
SET #Command = 'RENAME "' + #NewMyDBLogOriginalFileName + '" "MyDB_log.mdf"'; PRINT #Command
EXEC xp_cmdshell #Command
-- Attach with new file names
declare #NewMyDBFileNameAfterRename nvarchar(300) = replace(#NewMyDBOriginalFileName, 'NewMyDB', 'MyDB')
declare #NewMyDBLogFileNameAfterRename nvarchar(300) = replace(#NewMyDBOriginalFileName, 'NewMyDB_log', 'MyDB_log')
SET #Sql = 'CREATE DATABASE MyDB ON ( FILENAME = ''' + #NewMyDBFileNameAfterRename + '''), ( FILENAME = ''' + #NewMyDBLogFileNameAfterRename + ''') FOR ATTACH'
PRINT #Sql
EXEC (#Sql)
ALTER DATABASE MyDB SET MULTI_USER
END
-- Disable xp_cmdshell for security reasons:
GO
sp_configure 'show advanced options', 1
RECONFIGURE WITH OVERRIDE
GO
sp_configure 'xp_cmdshell', 0
RECONFIGURE WITH OVERRIDE
GO
You can do it using an ALTER DATABASE statement - like this:
ALTER DATABASE database_name
MODIFY FILE ( NAME = logical_file_name,
FILENAME = ' new_path/os_file_name_with_extension ' )
You need to modify each file separately, e.g. if you have multiple data files, you need to modify each of those.
For details, see the Technet documentation on this topic.
The simplest way to rename SQL server physical database files is:
Open and connect to the SQL server where the database you wanted to rename is located.
Execute the following script in the query window in order to change the physical and logical names. Remember to replace all the "OldDatabaseName" with the new name of the database ("NewDatabaseName") you want to change its name to. Replace all NewDatabaseName with the new name you want to set for your database
use OldDatabaseName
ALTER DATABASE OldDabaseName MODIFY FILE (NAME='OldDatabaseName', FILENAME='C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\NewDatabaseName.mdf');
ALTER DATABASE OldDatabaseName MODIFY FILE (NAME='OldDatabaseName_log', FILENAME='C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\NewDatabaseName_log.ldf');
ALTER DATABASE OldDatabaseName MODIFY FILE (NAME = OldDatabaseName, NEWNAME = NewDatabaseName);
ALTER DATABASE OldDatabaseName MODIFY FILE (NAME = OldDatabaseName_log, NEWNAME = NewDatabaseName_log);
And then Right click on the OldDatabaseName, select Tasks and then choose Take Offline
Go to the location (C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\...) where the physical files are located and rename them to the NewDatabaseName you specified in number 2. Remember to check the absolute path of these files to be used on your computer.
Go back to Microsoft SQL Server Management Studio. Right click on the OldDatabaseName, select Tasks and then choose Bring Online.
Finally, go ahead and rename your OldDatabaseName to the NewDatabaseName. You are done :-)
Detach (right click on database)
Rename both files (ldf and mdf) :
C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA
Attach (right click on "Databases" top folder)

What's the best way to create a working copy of a SQL Server database?

I have a SQL database that I am currently converting from an Access database. One of the features of the Access database is to 'Copy DB' and is used when working in a 'dev' site - it copies all of the production data by physically copying the production file into the dev site. In this way, all production data and structure and queries and everything is duplicated into the dev version. This only needs to be done occasionally when we are testing why something is occurring and we don't want to play in production data; not rare, but not frequent either - perhaps once or twice a month. I'm wondering what have other people done to accomplish this when working in SQL?
I'm thinking that I could do a DB backup followed by a restore to the DEV version, but I don't want this backup to interfere with normal backup processes. Is there any way to do this from one DB straight to another instead of going to the file system, and have the backup seem like it never happened (i.e. the REAL backup will still back up all items that really needed to be backed up)?
What other options are there? I have SQL Compare and SQL Data Compare from Red Gate, but I need to expose this functionality to certain users (with high privs and access to the DEV site), and they don't have it.
Ok well after looking around a bit, I've come to the conclusion that I do have to go thru the file system, but there is a way to do a backup/restore without affecting the normal backup process by using 'Copy Only' mode. Here's script to do it:
BACKUP DATABASE [ProductionDB]
TO DISK = N'D:\ProductionDBToDevTransfer.bak'
WITH
COPY_ONLY,
NOFORMAT,
INIT,
NAME = N'DB-Full Backup',
SKIP,
NOREWIND,
NOUNLOAD,
STATS = 10
RESTORE DATABASE [DevDB]
FROM DISK = N'D:\ProductionDBToDevTransfer.bak'
WITH
FILE = 1,
MOVE N'ProductionDB' TO N'D:\Microsoft\SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\DevDB.mdf',
MOVE N'ProductionDB_log' TO N'D:\Microsoft\SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\DevDB_log.ldf',
NOUNLOAD,
REPLACE,
STATS = 10
Take particular note of the MOVE statements in the RESTORE command... by default, the RESTORE will restore files to the originally backed up physical files, NOT the Dev DB files, despite the fact that you are restoring to the DEV db... I ALMOST found out the hard way, when I did the restore, and SSMS complained that the files were in use by ANOTHER db... OMG, how non-intuitive.
The script above works, but doesn't change the logical file name for the copied server. So, if you try and run it again to reverse the process it will fail in the MOVE statements.
I modified the script a little and came up with the following which seems to work for me. I'm new to this, so be careful!
DECLARE #SOURCEDB nvarchar(100)
DECLARE #SOURCEDBLOG nvarchar(100)
DECLARE #DESTINATIONDB nvarchar(100)
DECLARE #DESTINATIONDBLOG nvarchar(100)
DECLARE #BACKUPDIR nvarchar(100)
DECLARE #BACKUPFILE nvarchar(100)
DECLARE #BACKUPNAME nvarchar(100)
DECLARE #SQLDATADIR nvarchar(100)
DECLARE #SQLDATABACKUPFILE nvarchar(100)
DECLARE #SQLDATABACKUPLOGFILE nvarchar(100)
--CHANGE THESE VALUES TO MATCH YOUR SYSTEM
SET #SOURCEDB = N'test'
SET #DESTINATIONDB = N'test-backup'
SET #BACKUPDIR = N'C:\SHARED\'
SET #SQLDATADIR = N'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\'
--CALCULATED VALUES
SET #SOURCEDBLOG = #SOURCEDB + N'_log'
SET #DESTINATIONDBLOG = #DESTINATIONDB + N'_log'
SET #BACKUPFILE = #BACKUPDIR + #SOURCEDB + N'-to-' + #DESTINATIONDB + N'.bak'
SET #BACKUPNAME = #SOURCEDB + N'-Full Backup'
SET #SQLDATABACKUPFILE = #SQLDATADIR + #DESTINATIONDB + N'.mdf'
SET #SQLDATABACKUPLOGFILE = #SQLDATADIR + #DESTINATIONDBLOG + N'.ldf'
--BACKUP THE DATABASE
BACKUP DATABASE #SOURCEDB
TO DISK = #BACKUPFILE
WITH
COPY_ONLY,
NOFORMAT,
INIT,
NAME = #BACKUPNAME,
SKIP,
NOREWIND,
NOUNLOAD,
STATS = 10
--RESTORE THE BACKUP TO THE NEW DATABASE NAME
RESTORE DATABASE #DESTINATIONDB
FROM DISK = #BACKUPFILE
WITH
FILE = 1,
MOVE #SOURCEDB TO #SQLDATABACKUPFILE,
MOVE #SOURCEDBLOG TO #SQLDATABACKUPLOGFILE,
NOUNLOAD,
REPLACE,
STATS = 10
--UPDATE THE LOGICAL FILE NAMES
DECLARE #TEMPLATE varchar(500)
DECLARE #SCRIPT varchar(500)
SET #TEMPLATE = N'ALTER DATABASE [{DBNAME}] MODIFY FILE (NAME = [{OLD}], NEWNAME = [{NEW}])'
SET #SCRIPT = REPLACE(REPLACE(REPLACE(#TEMPLATE, '{DBNAME}', #DESTINATIONDB),'{OLD}',#SOURCEDB),'{NEW}',#DESTINATIONDB)
EXEC(#SCRIPT)
SET #SCRIPT = REPLACE(REPLACE(REPLACE(#TEMPLATE, '{DBNAME}', #DESTINATIONDB),'{OLD}',#SOURCEDBLOG),'{NEW}',#DESTINATIONDBLOG)
EXEC(#SCRIPT)
You can restore a database directly from another database.
If you're using SQL Management Studio, select "From database" instead of "From device" in the Restore Database dialog box.
You generally want to restore a whole database from a backup. Trying to do it directly from a live running prod database could cause locking issues for your users. You can do this using SSIS, but it is neither a simple nor quick thing to set up properly.
Another possibility is if you can turn off prod for a time being (only if you have a time period when users are not inthe database). Then detach the database. Detach the dev database and delete it. Copy the file to the dev server and attach both databases again. This can be faster than a restore, but it is a rare environment now that doesn't have 24 hour data access on production.
Incidentally it is very much preferable to have dev and prod on separate servers.
And if you are restoring to dev, you need to make sure any dev changes that have not yet been committed to prod are scripted, so they can be run immediately after the restore. It's best if you script any and all database changes and store them in source control. That makes it easier to do this.
We do an on-demand backup of the production data, and then restore the backup on the dev machine.

What is a simple command line program or script to backup SQL server databases?

I've been too lax with performing DB backups on our internal servers.
Is there a simple command line program that I can use to backup certain databases in SQL Server 2005? Or is there a simple VBScript?
To backup a single database from the command line, use osql or sqlcmd.
"C:\Program Files\Microsoft SQL Server\90\Tools\Binn\osql.exe"
-E -Q "BACKUP DATABASE mydatabase TO DISK='C:\tmp\db.bak' WITH FORMAT"
You'll also want to read the documentation on BACKUP and RESTORE and general procedures.
I use ExpressMaint.
To backup all user databases I do for example:
C:\>ExpressMaint.exe -S (local)\sqlexpress -D ALL_USER -T DB -BU HOURS -BV 1 -B c:\backupdir\ -DS
Schedule the following to backup all Databases:
Use Master
Declare #ToExecute VarChar(8000)
Select #ToExecute = Coalesce(#ToExecute + 'Backup Database ' + [Name] + ' To Disk = ''D:\Backups\Databases\' + [Name] + '.bak'' With Format;' + char(13),'')
From
Master..Sysdatabases
Where
[Name] Not In ('tempdb')
and databasepropertyex ([Name],'Status') = 'online'
Execute(#ToExecute)
There are also more details on my blog: how to Automate SQL Server Express Backups.
I found this on a Microsoft Support page http://support.microsoft.com/kb/2019698.
It works great! And since it came from Microsoft, I feel like it's pretty legit.
Basically there are two steps.
Create a stored procedure in your master db. See msft link or if it's broken try here: http://pastebin.com/svRLkqnq
Schedule the backup from your task scheduler. You might want to put into a .bat or .cmd file first and then schedule that file.
sqlcmd -S YOUR_SERVER_NAME\SQLEXPRESS -E -Q "EXEC sp_BackupDatabases #backupLocation='C:\SQL_Backup\', #backupType='F'" 1>c:\SQL_Backup\backup.log
Obviously replace YOUR_SERVER_NAME with your computer name or optionally try .\SQLEXPRESS and make sure the backup folder exists. In this case it's trying to put it into c:\SQL_Backup
I'm using tsql on a Linux/UNIX infrastructure to access MSSQL databases. Here's a simple shell script to dump a table to a file:
#!/usr/bin/ksh
#
#.....
(
tsql -S {database} -U {user} -P {password} <<EOF
select * from {table}
go
quit
EOF
) >{output_file.dump}
You can use the backup application by ApexSQL. Although it’s a GUI application, it has all its features supported in CLI. It is possible to either perform one-time backup operations, or to create a job that would back up specified databases on the regular basis. You can check the switch rules and exampled in the articles:
ApexSQL Backup CLI support
ApexSQL Backup CLI examples
Eventual if you don't have a trusted connection as the –E switch declares
Use following command line
"[program dir]\[sql server version]\Tools\Binn\osql.exe" -Q "BACKUP DATABASE mydatabase TO DISK='C:\tmp\db.bak'" -S [server] –U [login id] -P [password]
Where
[program dir] is the directory where the osql.exe exists
On 32bit OS c:\Program Files\Microsoft SQL Server\
On 64bit OS c:\Program Files (x86)\Microsoft SQL Server\
[sql server version] your sql server version 110 or 100 or 90 or 80 begin with the largest number
[server] your servername or server ip
[login id] your ms-sql server user login name
[password] the required login password
Microsoft's answer to backing up all user databases on SQL Express is here:
The process is: copy, paste, and execute their code (see below. I've commented some oddly non-commented lines at the top) as a query on your database server. That means you should first install the SQL Server Management Studio (or otherwise connect to your database server with SSMS). This code execution will create a stored procedure on your database server.
Create a batch file to execute the stored procedure, then use Task Scheduler to schedule a periodic (e.g. nightly) run of this batch file. My code (that works) is a slightly modified version of their first example:
sqlcmd -S .\SQLEXPRESS -E -Q "EXEC sp_BackupDatabases #backupLocation='E:\SQLBackups\', #backupType='F'"
This worked for me, and I like it. Each time you run it, new backup files are created. You'll need to devise a method of deleting old backup files on a routine basis. I already have a routine that does that sort of thing, so I'll keep a couple of days' worth of backups on disk (long enough for them to get backed up by my normal backup routine), then I'll delete them. In other words, I'll always have a few days' worth of backups on hand without having to restore from my backup system.
I'll paste Microsoft's stored procedure creation script below:
--// Copyright © Microsoft Corporation. All Rights Reserved.
--// This code released under the terms of the
--// Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)
USE [master]
GO
/****** Object: StoredProcedure [dbo].[sp_BackupDatabases] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Microsoft
-- Create date: 2010-02-06
-- Description: Backup Databases for SQLExpress
-- Parameter1: databaseName
-- Parameter2: backupType F=full, D=differential, L=log
-- Parameter3: backup file location
-- =============================================
CREATE PROCEDURE [dbo].[sp_BackupDatabases]
#databaseName sysname = null,
#backupType CHAR(1),
#backupLocation nvarchar(200)
AS
SET NOCOUNT ON;
DECLARE #DBs TABLE
(
ID int IDENTITY PRIMARY KEY,
DBNAME nvarchar(500)
)
-- Pick out only databases which are online in case ALL databases are chosen to be backed up
-- If specific database is chosen to be backed up only pick that out from #DBs
INSERT INTO #DBs (DBNAME)
SELECT Name FROM master.sys.databases
where state=0
AND name=#DatabaseName
OR #DatabaseName IS NULL
ORDER BY Name
-- Filter out databases which do not need to backed up
IF #backupType='F'
BEGIN
DELETE #DBs where DBNAME IN ('tempdb','Northwind','pubs','AdventureWorks')
END
ELSE IF #backupType='D'
BEGIN
DELETE #DBs where DBNAME IN ('tempdb','Northwind','pubs','master','AdventureWorks')
END
ELSE IF #backupType='L'
BEGIN
DELETE #DBs where DBNAME IN ('tempdb','Northwind','pubs','master','AdventureWorks')
END
ELSE
BEGIN
RETURN
END
-- Declare variables
DECLARE #BackupName varchar(100)
DECLARE #BackupFile varchar(100)
DECLARE #DBNAME varchar(300)
DECLARE #sqlCommand NVARCHAR(1000)
DECLARE #dateTime NVARCHAR(20)
DECLARE #Loop int
-- Loop through the databases one by one
SELECT #Loop = min(ID) FROM #DBs
WHILE #Loop IS NOT NULL
BEGIN
-- Database Names have to be in [dbname] format since some have - or _ in their name
SET #DBNAME = '['+(SELECT DBNAME FROM #DBs WHERE ID = #Loop)+']'
-- Set the current date and time n yyyyhhmmss format
SET #dateTime = REPLACE(CONVERT(VARCHAR, GETDATE(),101),'/','') + '_' + REPLACE(CONVERT(VARCHAR, GETDATE(),108),':','')
-- Create backup filename in path\filename.extension format for full,diff and log backups
IF #backupType = 'F'
SET #BackupFile = #backupLocation+REPLACE(REPLACE(#DBNAME, '[',''),']','')+ '_FULL_'+ #dateTime+ '.BAK'
ELSE IF #backupType = 'D'
SET #BackupFile = #backupLocation+REPLACE(REPLACE(#DBNAME, '[',''),']','')+ '_DIFF_'+ #dateTime+ '.BAK'
ELSE IF #backupType = 'L'
SET #BackupFile = #backupLocation+REPLACE(REPLACE(#DBNAME, '[',''),']','')+ '_LOG_'+ #dateTime+ '.TRN'
-- Provide the backup a name for storing in the media
IF #backupType = 'F'
SET #BackupName = REPLACE(REPLACE(#DBNAME,'[',''),']','') +' full backup for '+ #dateTime
IF #backupType = 'D'
SET #BackupName = REPLACE(REPLACE(#DBNAME,'[',''),']','') +' differential backup for '+ #dateTime
IF #backupType = 'L'
SET #BackupName = REPLACE(REPLACE(#DBNAME,'[',''),']','') +' log backup for '+ #dateTime
-- Generate the dynamic SQL command to be executed
IF #backupType = 'F'
BEGIN
SET #sqlCommand = 'BACKUP DATABASE ' +#DBNAME+ ' TO DISK = '''+#BackupFile+ ''' WITH INIT, NAME= ''' +#BackupName+''', NOSKIP, NOFORMAT'
END
IF #backupType = 'D'
BEGIN
SET #sqlCommand = 'BACKUP DATABASE ' +#DBNAME+ ' TO DISK = '''+#BackupFile+ ''' WITH DIFFERENTIAL, INIT, NAME= ''' +#BackupName+''', NOSKIP, NOFORMAT'
END
IF #backupType = 'L'
BEGIN
SET #sqlCommand = 'BACKUP LOG ' +#DBNAME+ ' TO DISK = '''+#BackupFile+ ''' WITH INIT, NAME= ''' +#BackupName+''', NOSKIP, NOFORMAT'
END
-- Execute the generated SQL command
EXEC(#sqlCommand)
-- Goto the next database
SELECT #Loop = min(ID) FROM #DBs where ID>#Loop
END​
Here is an example one, it will take backup database, compress using 7zip and delete backup file so issue related to storage also solved. In this example I use 7zip, which is free
#echo off
CLS
echo Running dump ...
sqlcmd -S SERVER\SQLEXPRESS -U username -P password -Q "BACKUP DATABASE master TO DISK='D:\DailyDBBackup\DB_master_%date:~-10,2%%date:~-7,2%%date:~-4,4%.bak'"
echo Zipping ...
"C:\Program Files\7-Zip\7z.exe" a -tzip "D:\DailyDBBackup\DB_master_%date:~-10,2%%date:~-7,2%%date:~-4,4%_%time:~0,2%%time:~3,2%%time:~6,2%.bak.zip" "D:\DailyDBBackup\DB_master_%date:~-10,2%%date:~-7,2%%date:~-4,4%.bak"
echo Deleting the SQL file ...
del "D:\DailyDBBackup\DB_master_%date:~-10,2%%date:~-7,2%%date:~-4,4%.bak"
echo Done!
Save this as sqlbackup.bat and schedule it to be run everyday.
If you just want to take backup only then you can create script without zipping and deleting.
You could use a VB Script I wrote exactly for this purpose:
https://github.com/ezrarieben/mssql-backup-vbs/
Schedule a task in the "Task Scheduler" to execute the script as you like and it'll backup the entire DB to a BAK file and save it wherever you specify.
SET NOCOUNT ON;
declare #PATH VARCHAR(200)='D:\MyBackupFolder\'
-- path where you want to take backups
IF OBJECT_ID('TEMPDB..#back') IS NOT NULL
DROP TABLE #back
CREATE TABLE #back
(
RN INT IDENTITY (1,1),
DatabaseName NVARCHAR(200)
)
INSERT INTO #back
SELECT 'MyDatabase1'
UNION SELECT 'MyDatabase2'
UNION SELECT 'MyDatabase3'
UNION SELECT 'MyDatabase4'
-- your databases List
DECLARE #COUNT INT =0 , #RN INT =1, #SCRIPT NVARCHAR(MAX)='', #DBNAME VARCHAR(200)
PRINT '---------------------FULL BACKUP SCRIPT-------------------------'+CHAR(10)
SET #COUNT = (SELECT COUNT(*) FROM #back)
PRINT 'USE MASTER'+CHAR(10)
WHILE(#COUNT > = #RN)
BEGIN
SET #DBNAME =(SELECT DatabaseName FROM #back WHERE RN=#RN)
SET #SCRIPT ='BACKUP DATABASE ' +'['+#DBNAME+']'+CHAR(10)+'TO DISK =N'''+#PATH+#DBNAME+ N'_Backup_'
+ REPLACE ( REPLACE ( REPLACE ( REPLACE ( CAST ( CAST ( GETDATE () AS DATETIME2 ) AS VARCHAR ( 100 )), '-' , '_' ), ' ' , '_' ), '.' , '_' ), ':' , '' )+'.bak'''+CHAR(10)+'WITH COMPRESSION, STATS = 10'+CHAR(10)+'GO'+CHAR(10)
PRINT #SCRIPT
SET #RN=#RN+1
END
PRINT '---------------------DIFF BACKUP SCRIPT-------------------------'+CHAR(10)
SET #COUNT =0 SET #RN =1 SET #SCRIPT ='' SET #DBNAME =''
SET #COUNT = (SELECT COUNT(*) FROM #back)
PRINT 'USE MASTER'+CHAR(10)
WHILE(#COUNT > = #RN)
BEGIN
SET #DBNAME =(SELECT DatabaseName FROM #back WHERE RN=#RN)
SET #SCRIPT ='BACKUP DATABASE ' +'['+#DBNAME+']'+CHAR(10)+'TO DISK =N'''+#PATH+#DBNAME+ N'_Backup_'
+ REPLACE ( REPLACE ( REPLACE ( REPLACE ( CAST ( CAST ( GETDATE () AS DATETIME2 ) AS VARCHAR ( 100 )), '-' , '_' ), ' ' , '_' ), '.' , '_' ), ':' , '' )+'.diff'''+CHAR(10)+'WITH DIFFERENTIAL, COMPRESSION, STATS = 10'+CHAR(10)+'GO'+CHAR(10)
PRINT #SCRIPT
SET #RN=#RN+1
END
This can be helpful when you are dealing with dockerised mssql container in your day to day work and want to take a quick dump of the data from table. I have specially found it useful when you are re-building the db container quite frequently and don't want to loose the test data after the re-build.
Export data using bcp utility
/opt/mssql-tools/bin/bcp <Table_Name> out /tmp/MyData.bcp -d <database_name> -c -U <user_name> -P "<password>" -S <server_name>
Import data using bcp utility
/opt/mssql-tools/bin/bcp <Table_Name> IN /tmp/MyData.bcp -d <database_name> -c -U <user_name> -P "<password>" -S <server_name>
If you can find the DB files... "cp DBFiles backup/"
Almost for sure not advisable in most cases, but it's simple as all getup.

Resources