How Do I Save SQL Server Backup with Date Filename - sql

Hi can I convert the following code so that the backup includes the date and time in the filename.
USE SysproCompany
GO
EXEC('BACKUP DATABASE [Company] TO DISK = N''G:\SQLBackups\INSTANCE1\MonthEndBackup\Company\MonthEndBackup.bak'' WITH NOFORMAT, COPY_ONLY,INIT,
NAME = N''MonthEndBackup'', SKIP, NOREWIND, NOUNLOAD, STATS = 10
')
PRINT 'Backup of Syspro Company started'
GO
PRINT 'Backup of Syspro Company complete'

You don't need exec to begin with. Just execute
BACKUP DATABASE [Company]
TO DISK = N''G:\SQLBackups\INSTANCE1\MonthEndBackup\Company\MonthEndBackup.bak''
WITH NOFORMAT, COPY_ONLY,INIT,
NAME = N''MonthEndBackup'', SKIP, NOREWIND, NOUNLOAD, STATS = 10
You'll have to specify the file name yourself, paths don't use formatting characters or patterns. After all, different DBAs use completely different folder and naming conventions. You can calculate the name in a variable before you use it.
A far better option though, the one used by most DBAs, is to use Ola Hallengren's backup scripts to specify settings, folder and filename patterns, for multiple databases at a time.
The default pattern filename pattern is
'{ServerName}${InstanceName}_{DatabaseName}_{BackupType}_{Partial}_{CopyOnly}_{Year}{Month}{Day}_{Hour}{Minute}{Second}_{FileNumber}.{FileExtension}',
A single command can be used to perform multiple operations, eg both backup all user databases and verify the backups, and clean up old backups :
EXECUTE dbo.DatabaseBackup
#Databases = 'USER_DATABASES',
#Directory = 'C:\Backup',
#BackupType = 'FULL',
#Verify = 'Y',
#Compress = 'Y',
#CheckSum = 'Y',
#CleanupTime = 24

Try this:
EXEC('BACKUP DATABASE [Company] TO DISK = N''G:\SQLBackups\INSTANCE1\MonthEndBackup\Company\MonthEndBackup' + CURRENT_TIMESTAMP + '.bak'' WITH NOFORMAT, COPY_ONLY,INIT,
NAME = N''MonthEndBackup'', SKIP, NOREWIND, NOUNLOAD, STATS = 10
')

Related

Why is my Ola Hallengren log back up retention not clearing down old log files?

I have set up Ola Hallengren in a UAT environment to perform transaction log back ups with a 2 day retention on AOAG databases on a secondary node. On the same node I am also taking copy_only database back ups. You will see from my code that I am specifying 'User_Databases' as opposed to specifying the AOAG. The reason for this is because I need to exclude some AOAG DBs from the db back up job and therefore used the same approach on the tlog back up job.
trn:
EXECUTE [dbo].[DatabaseBackup]
#Databases = 'USER_DATABASES',
#Directory = N'G:\SQLLogs\UserDB',
#BackupType = 'LOG',
#Verify = 'Y',
#CopyOnly = 'N',
#CleanupTime = 48,
#CheckSum = 'Y',
#overridebackuppreference = 'Y',
#availabilitygroupdirectorystructure = '{DatabaseName}_{BackupType}_{CopyOnly}',
#AvailabilityGroupFileName = '{DatabaseName}_{Year}{Month}{Day}_{Hour}{Minute}{Second}_{FileNumber}.{FileExtension}',
#directorystructure = '{DatabaseName}_{BackupType}_{CopyOnly}',
#FileName = '{DatabaseName}_{Year}{Month}{Day}_{Hour}{Minute}{Second}_{FileNumber}.{FileExtension}'
bak:
EXECUTE [dbo].[DatabaseBackup]
#Databases = 'USER_DATABASES, -%excludeDB%',
#Directory = N'E:\SQLBackups\UserDB',
#BackupType = 'FULL',
#Verify = 'Y',
#CopyOnly = 'Y',
#CleanupTime = 48,
#CheckSum = 'Y',
#overridebackuppreference = 'Y',
#availabilitygroupdirectorystructure = '{DatabaseName}_{BackupType}_{CopyOnly}',
#AvailabilityGroupFileName = '{DatabaseName}_{Year}{Month}{Day}_{Hour}{Minute}{Second}_{FileNumber}.{FileExtension}',
#directorystructure = '{DatabaseName}_{BackupType}_{CopyOnly}',
#FileName = '{DatabaseName}_{Year}{Month}{Day}_{Hour}{Minute}{Second}_{FileNumber}.{FileExtension}'
The bak and trn back ups complete as expected and the baks are cleared down when older than 48 hours, however the log back ups build up.
Can anyone see what is wrong here that is preventing the logs from clearing down?

Last modification Date file system by creating a script

I need to create an script or query to give me the last modification date of a file system. I have the below query and it works perfectly for an overwitted backup file. but I need to run it for *.bak that shows me the latest backup file modification date during many backup files:
--
if exists(select 1 from tempdb..sysobjects where name='##tmp')
drop table ##tmp
create table ##tmp(mdate varchar(8000))
insert ##tmp
exec master.dbo.xp_cmdshell 'dir g:\SQL_Backup\filename.bak' -- (I need the --last backup file name which the name keep changing every week)
set rowcount 5
delete from ##tmp
set rowcount 0
select top(1) substring(mdate,1,20) as 'Last modified date' from ##tmp
I've never worked with these views, so this really need a reality check before you really integrate it, but this may help:
select
top 1 backupSetName = bs.name,
backupFilePath = bf.physical_name,
backupFileLogicalName = bf.logical_name,
bs.backup_start_date,
bs.backup_finish_date
from msdb.dbo.backupfile bf
join msdb.dbo.backupSet bs on bf.backup_set_id = bs.backup_set_id
where right(bf.physical_name,4) = '.mdf'
order by backup_finish_date desc;
"Backup Set" records the actual dates. Since it is one-to-many with "Backup Files", it means that the '.mdf' and '.ldf' file dates are recorded together. I just excluded the latter in the above output.
I can run the PowerShell script and store in in sql server job. It ran successfully.
$source = "\00.0.00.00\your file location"
$filetype = "dif" (or "bak")
Get-ChildItem "$source*" -Include "*.$filetype" | sort LastWriteTime | select -last 1
$datetime=[datetime]::Today
if($datetime.DayOfWeek -match 'Monday'){
Write-Host "YES"
}elseif($datetime.DayOfWeek -match 'Tuesday|Thursday|Saturday'){
Write-Host "NO"
}else{
Write-Host "YES"
}

Sending query results via email via email attachment every first day of every month on SQL Server 2012

My requirement:
Send the query result via email attachment on first day of every month.
The work I've been doing manually:
I have to run this query every first day of each month by changing the date range.
Then I export the result acquired in .csv format and send this csv file as an attachment
I needed suggestions from you people on how shall I automate this process:
Shall I set up a Job on SQL Server 2012, but yes, the I'll have to modify the date range.
Please suggest on how to move forward.
Any help, much appreciated.
As you mentioned, Create a Job and schedule it to run on first day of every month. Considering you have enough knowledge on creating a job.
Go to Job properties -> schedules -> and make the following setting
Occurs every first day of every 1 month(s) at 12:00:00. Schedule will
be used starting on 07-12-2016.
Change the timing(at which time it should run on first day of month) based on your business requirement. It can be set under Daily frequency-> Occurs once at:
This process can also be automated by another way by using a Windows batch file.You can schedule it using Windows scheduler.
Below will be contents of batch file
Echo off
sqlcmd -u <username> -p <password> -S <server name> -d <database name> -i <sql file location> -o <output result file location>
Powershell.exe -executionpolicy remotesigned -File <location of powershell file>
The powershell file trigger an email when bat file is run.
Contents of powershell file
$smtpserver = "<smtp server name>"
$from="mail id"
$to="<mail id"
$a = Get-Date
$subject= "<subject line> `r"+ $a.Month +"/"+$a.Day +"/"+ $a.Year
$body=""
$attachment="File location"
Thanks,`n "
$mailer = new-object Net.Mail.SMTPclient($smtpserver)
$msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body,$data1,$a)
$msg.IsBodyHTML = $true
$mailer.send($msg)
I use SQL Agent for send results via email like this:
/*
First you should set up SQL Mail Profile.
Please change #dbName, #SQLscript, #mailbody and mail account values. When changing your #SQLscript value be careful that replace (with CTRL+H) single quota (') to double quotas ('').
*/
DECLARE #dbName nvarchar(50), #SQLscript nvarchar(4000), #subject varchar(100), #mailfrom varchar(100), #mailbody nvarchar(4000), #jobName varchar(100)
SELECT #jobName = name from msdb..sysjobs where job_id = $(ESCAPE_NONE(JOBID))
SELECT #mailfrom = ##SERVICENAME + ' <' + cast(SERVERPROPERTY('ComputerNamePhysicalNETBIOS') as varchar(50)) + '#domain.com>'
SELECT #subject = N'SQL Server Job Result [Job: ' + #jobName + ']'
SELECT #dbName = 'Database'
SELECT #SQLscript = '
INSERT INTO [Database].[Schema].[Table] (
Column1
,Column2
) VALUES (
''Value1''
,''Value2'' )
'
SELECT #mailbody = N'
Depending on case number 1234-5678-90 your script executed on <b>' + ##SERVERNAME + N'</b> instance and <b>' + #dbName + '</b> database. Script info and results are shown below. <br><br>' +
'<b>Script: </b><br>' + #SQLscript + '<br><br>' +
'<b>Result: </b><br>'
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'sqlmailprofile',
#recipients = '<mail1#domain.com>;<mail2#domain.com>',
#copy_recipients = '<mail3#domain.com>',
#from_address = #mailfrom,
#reply_to = '<mail3#domain.com>',
#subject = #subject,
#body = #mailbody,
#body_format = 'HTML',
#importance = 'HIGH',
#execute_query_database = #dbName,
#query = #SQLscript
/* If you want to send results with attached file:
#attach_query_result_as_file = 1,
#query_attachment_filename = 'script_output.csv',
#query_result_separator=#tab,
#query_result_width =32767,
#query_result_no_padding=1,
#exclude_query_output=1,
#query_result_header=1
*/

How to check when autogrowth is done last?

In sql server 2005, the autogrowth is enabled by size.
Is there any way to check when autogrowth on data and log file happened last?
SSMS, right click your db, go to reports->standard reports->disk usage and look for Autogrow/Autoshrink events .
Hopefully you have the correct trace levels set up, if not you might have some issues finding out history.
Here's how to do it without using the sql reports(link, followed by relevant TSQL):
https://sqlblog.org/2007/01/11/reviewing-autogrow-events-from-the-default-trace
DECLARE #path NVARCHAR(260);
SELECT
#path = REVERSE(SUBSTRING(REVERSE([path]),
CHARINDEX('\', REVERSE([path])), 260)) + N'log.trc'
FROM sys.traces
WHERE is_default = 1;
SELECT
DatabaseName,
[FileName],
SPID,
Duration,
StartTime,
EndTime,
FileType = CASE EventClass
WHEN 92 THEN 'Data'
WHEN 93 THEN 'Log'
END
FROM sys.fn_trace_gettable(#path, DEFAULT)
WHERE
EventClass IN (92,93)
ORDER BY
StartTime DESC;

Add date to SQL database backup filename

I'm using the below to backup a db from a SQL job. Can someone tell me how to add the current date to the output filename? Preferably in YYYYMMDD format.
BACKUP DATABASE [myDB] TO  DISK = N'\\myPath\myDB.bak' WITH NOFORMAT, INIT,  NAME = N'myDB', SKIP, REWIND, NOUNLOAD,  STATS = 10
GO
Thanks!
DECLARE #MyFileName varchar(1000)
SELECT #MyFileName = (SELECT '\\ServerToSave\Path\MyDB_' + convert(varchar(500),GetDate(),112) + '.bak')
BACKUP DATABASE [myDB] TO DISK=#MyFileName ...
If you want to include the date and time, so you can use:
DECLARE #MyFileName varchar(200)
SELECT #MyFileName='\\ServerToSave\Path\MyDB_' + REPLACE(convert(nvarchar(20),GetDate(),120),':','-') + '.bak'
BACKUP DATABASE [myDB] TO DISK=#MyFileName ...
The 120 in the Convert gives you the yyyy-mm-dd hh:mi:ss(24h)
The REPLACE function is necessary because the filename can not have the : character.
Try this.
DECLARE #MyFileName varchar(50)
SELECT '\\ServerToSave\Path\MyDB_' + convert(nvarchar(20),GetDate(),112) + '.bak'
BACKUP DATABASE [myDB] TO DISK=#MyFileName ...
The 112 in the Convert gives you the YYYYMMDD format
Use the following
DECLARE #BackupFileName varchar(20)
SELECT #BackupFileName = '\\ServerName\SharedFolder\DatabaseName_' + CONVERT (VarChar, GetDate(), 112) + '.bak'
BACKUP DATABASE [myDB] TO DISK = #BackupFileName WITH NOFORMAT, INIT, NAME = N'myDB', SKIP, REWIND, NOUNLOAD, STATS = 10
Read up on Cast and Convert here http://msdn.microsoft.com/en-us/library/ms187928.aspx
Maybe you want to use windows task, just put this code in a .BAT file and add to your Windows tasks:
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%"
set "fullstamp=%YYYY%%MM%%DD%-%HH%%Min%%Sec%"
set bkfile=D:\bk-sqlserver\dbname%fullstamp%.bak
set path_sqlcmd="C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn\SQLCMD.exe"
%path_sqlcmd% -S .\SQLEXPRESS -E -Q "BACKUP DATABASE dbname TO DISK='%bkfile%' WITH FORMAT"
It's a bit long, but i think it's a practical solution.
Use sqlcmd for SQL Server 2005 or later
Use osql for SQL Server 2000 or oldies
DECLARE #var nvarchar(max) ='C:\Projects\myDatabase ' +replace(rtrim(convert(char,getdate())), ':',',')+'.bak';
BACKUP DATABASE myDatabase TO DISK = #var
output:
C:\Projects\myDatabase Jun 3 2015 6,33AM.bak
You can use any of them.
These Are Sample For Use Date And DateTime In Backup Database:
SELECT 'TestDb' + '_'+CAST(CAST(GETDATE() AS datetime2) AS NVARCHAR(22))+
'_Log.trn';--TestDb_2019-09-28 13:54:42.54_Log.trn
SELECT 'TestDb' + '_'+CAST(CAST(GETDATE() AS DATE) AS NVARCHAR(MAX))+
'_Log.trn';--TestDb_2019-09-28_Log.trn
SELECT 'TestDb' + '_'+CAST(sysdatetime() as nvarchar(max))+ '_Log.trn';--TestDb_2019-09-28 13:54:42.5536994_Log.trn
SELECT 'TestDb'+'_' + convert(varchar(500),GETDATE(),120) + '_Log.trn';--TestDb_2019-09-28 13:54:42_Log.trn
SELECT 'TestDb'+'_' + convert(varchar(500),GETDATE(),112) + '_Log.trn';--TestDb_20190928_Log.trn
SELECT 'TestDb' + '_'+CAST(FORMAT(getdate(), N'yyyy-MM-ddThh:mm:ss') as nvarchar(max))+ '_Log.trn';--TestDb_2019-09-28T02:08:38_Log.trn