Restore database with file name variable date script - tsql

I want to write a script that will restore the database by database name + today's date. Example: (test_01.05.2018.bak)
DECLARE #BackupFile as nvarchar(128);
SET #BackupFile = N'C:\backup\test1' + convert(varchar(12),Day(GETDATE()) -1) + (month(GETDATE()) * 100) + (year(GETDATE()) * 10000) + N'test1.bak'
USE master;
RESTORE DATABASE [TEST] FROM DISK = #BackupFile WITH FILE = 1,
MOVE N'test1' TO N'C:\db\TEST.mdf',
MOVE N'test1_log' TO N'C:\db\TEST_log.ldf',
NOUNLOAD, REPLACE, STATS = 10

Your query would have had date in YYYYMMDD and yesterdays date. It errors because of converion.
It could be rewritten with something like
DECLARE #BackupFile as nvarchar(128);
SET #BackupFile = N'C:\backup\test1' + CONVERT(NVARCHAR(8), DATEADD(DAY, -1, GETDATE()), 112) + N'test1.bak'
You'll still have to edit the other parts of the string as I couldn't make sense of it but this will get your there.

Related

PowerPoint: Add Date of Yesterday and Tomorrow to a Slide

I want to have a table on my PowerPoint (2016) slide which should look like this:
sysdate - 1
sysdate
sysdate + 1
02.09.2021
03.09.2021
04.09.2021
To keep the slides intuitive, the dates should be updated automatically.
By using Insert -> Text -> Date & Time I can add a field containing the current date for the center column.
How do I add a dynamic field for yesterday and tomorrow?
First, follow the steps here to name your table. After that, insert a module (Alt+F11, Insert - Module) and add this piece of code:
Sub SetTableHeaders()
Const SlideNo = 1
Const TableName = "TableName Here"
Dim MyTable As Table
Set MyTable = ActivePresentation.Slides(SlideNo).Shapes(TableName).Table
MyTable.Rows(1).Cells(1).Shape.TextFrame.TextRange.Text = Format(Now - 1, "yyyy-mm-dd")
MyTable.Rows(1).Cells(2).Shape.TextFrame.TextRange.Text = Format(Now, "yyyy-mm-dd")
MyTable.Rows(1).Cells(3).Shape.TextFrame.TextRange.Text = Format(Now + 1, "yyyy-mm-dd")
End Sub
Replace the SlideNo and TableName values with the right ones. Run it (F5) to set the headers.

Parse the backup\restore path and filename during the backup\restore

I'm writing a webapp that monitors backup and restores while they are happening. What I've been asked to add to it was a way to show the backup\restore path and filename as it's happening.
I'm able to, of course, get the command line that is running during the backup\restore so what I'd like to do is extract the path and filename from that command line.
So with my current code I am able to get this in a return by itself:
BACKUP DATABASE [DatabaseName] TO DISK = N'\\nas01\sqlbackups$\ServerName\DatabaseName.bak' WITH NOFORMAT, INIT, NAME = N'DatabaeName-Full Database Backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10
What I'd like to extract from that is \\nas01\sqlbackups$\ServerName\DatabaseName.bak
If not extracting from the code, is there a way to grab that from another table, while it's currently running?
This is the code I run to get the state of a current backup\restore:
SELECT r.session_id
,r.command
,CONVERT(NUMERIC(6, 2), r.percent_complete) AS [Percent Complete]
,CONVERT(VARCHAR(20), DATEADD(ms, r.estimated_completion_time, GetDate()), 20) AS [ETA Completion Time]
,CONVERT(NUMERIC(10, 2), r.total_elapsed_time / 1000.0 / 60.0) AS [Elapsed Min]
,CONVERT(NUMERIC(10, 2), r.total_elapsed_time / 1000.0 / 60.0 / 60.0) AS [Elapsed Hours]
,CONVERT(NUMERIC(10, 2), r.estimated_completion_time / 1000.0 / 60.0) AS [ETA Min]
,CONVERT(NUMERIC(10, 2), r.estimated_completion_time / 1000.0 / 60.0 / 60.0) AS [ETA Hours]
,CONVERT(VARCHAR(1000), (
SELECT SUBSTRING(TEXT, r.statement_start_offset / 2, CASE
WHEN r.statement_end_offset = - 1
THEN 1000
ELSE (r.statement_end_offset - r.statement_start_offset) / 2
END)
FROM sys.dm_exec_sql_text(sql_handle)
)) AS [TSQLCode]
FROM sys.dm_exec_requests r
WHERE command IN (
'RESTORE DATABASE'
,'BACKUP DATABASE'
,'BACKUP LOG'
,'RESTORE LOG'
)
I'm note sure, but I think Backup History can show you information about backup in progress. You could try, though. Otherwise, you can try to parse the command text. First remove the text prior "TO DISK", find the first and second quote and get the text between them. Use code like this:
declare #cmd nvarchar(max) = N'BACKUP DATABASE [DatabaseName] TO DISK = N''\\nas01\sqlbackups$\ServerName\DatabaseName.bak'' WITH NOFORMAT, INIT, NAME = N''DatabaeName-Full Database Backup'', SKIP, NOREWIND, NOUNLOAD, STATS = 10 '
-- Remove the text before "TO DISK"
set #cmd = SUBSTRING(#cmd, PATINDEX(N'%TO DISK%', #cmd), LEN(#cmd))
print #cmd
-- Remove the text before and including the first quote
set #cmd = SUBSTRING(#cmd, PATINDEX(N'%''%', #cmd) + 1, LEN(#cmd))
print #cmd
-- Get the text from the start to the next quote
set #cmd = SUBSTRING(#cmd, 1, PATINDEX(N'%''%', #cmd) - 1)
print #cmd

Dynamic SQL Error with REPLACE Statement

I am trying to create a script that builds a SQL statement dynamically and then executes it.
Here is the string that is built & stored in #strSQL (verified by using PRINT)
UPDATE DNN_RSM_Exams
SET ScoringDates = REPLACE(ScoringDates, '/2015', '/2016')
WHERE SchoolYear = 2015
It executes the variable as follows:
EXECUTE (#strSQL)
However I get the following error:
Conversion failed when converting the nvarchar value 'UPDATE DNN_RSM_Exams SET ScoringDates = REPLACE(ScoringDates, '/' to data type int.
It seems to terminate the EXECUTE when it hits the first forward-slash (/). I tried escaping it using a double slash (//), an open bracket ([), and a backslash (\). None if it worked.
Can anyone help me please?
UPDATE #01: 8/17/15
Sorry if I didn't give enough information initially...
ScoringDates is an NVARCHAR(MAX) field.
The Code that builds the SQL Statement is:
SET #strSQL = 'UPDATE ' + #strTableName +
' SET ScoringDates = REPLACE(ScoringDates, ''/' + LTRIM(RTRIM(STR(#intSchoolYear_CopyFrom + 1))) + ''', ''/' + LTRIM(RTRIM(STR(#intSchoolYear_CopyFrom + 2))) + ''')' +
' WHERE SchoolYear = ' + LTRIM(RTRIM(STR(#intSchoolYear_CopyTo)))
ScoringDates is a string based field that holds data in an INI-like formatted string. I want to change the year portion of ANY date found in the string, but I want to avoid accidental changes of any other numbers that may match. So I am specifically looking to replace "/YYYY" with a different "YYYY" value. The "/" preceding the year value is to ensure that what is being preplaced is the YEAR and not another numeric value within the string.
UPDATE #02: 8/18/15
So I am completely flabbergasted...after banging my head on this script for hours yesterday, I went home defeated. Come in today, start up my PC and run the script again so I can see the error message again...and it worked!
I've never come across this with SQL Management Studio, but it is possible that SQL Management Studio somehow lost it's marbles yesterday and needed a reboot? I thought the SQL was process by the server directly. Could it be that some is processed by the studio first before handing it off to the server and if the studio had "issues" then it would cause strange errors?
In any case, thank you so much guys for your input, I am sorry that it was a wheel spinner. It never occurred to me that a reboot would fix my issue, I just assumed my code was wrong.
You want to replace '/ with ''
So your set statement will be something like...
SET #strSQL = 'UPDATE DNN_RSM_Exams
SET ScoringDates = REPLACE(ScoringDates, ''2015'', ''2016'')
WHERE SchoolYear = 2015'
EDIT:
How is your code different than this below? (I will edit this again and clean it up after. Code just won't fit into comments)
DECLARE #TableName TABLE (ScoringDates VARCHAR(100), SchoolYear INT)
DECLARE #strTableName VARCHAR(MAX)
DECLARE #intSchoolYear_CopyFrom VARCHAR(MAX)
DECLARE #intSchoolYear_CopyTo VARCHAR(MAX)
SET #strTableName = '#TableName'
SET #intSchoolYear_CopyFrom = '2009'
SET #intSchoolYear_CopyTo = '2010'
DECLARE #strSQL VARCHAR(MAX)
SET #strSQL = 'DECLARE #TableName TABLE (ScoringDates VARCHAR(100), SchoolYear INT); UPDATE ' + #strTableName +
' SET ScoringDates = REPLACE(ScoringDates, ''/' + LTRIM(RTRIM(STR(#intSchoolYear_CopyFrom + 1))) + ''', ''/' + LTRIM(RTRIM(STR(#intSchoolYear_CopyFrom + 2))) + ''')' +
' WHERE SchoolYear = ' + LTRIM(RTRIM(STR(#intSchoolYear_CopyTo)))
PRINT #strSQL
EXECUTE (#strSQL)

Convert DD/MM/YYYY to YYYY-MM-DD at SQL server 2008 R2

I am using SSRS 2008, one report have text fields which takes data as DD/MM/YYYY as input, but at query i would like it to covert as YYYY-MM-DD.
I have tried with below code but could not succeed.
Declare #a varchar(20)= '27/03/2014'
SELECT CONVERT(varchar(20), CAST(#a as DATE),126)
Output required as
2014-03-27
In SSRS Report Date format Change use for this concept.
create table az(id integer,Dob varchar(20));
insert into az values(1, '25/03/2014')
insert into az values(2, '26/03/2014')
insert into az values(3, '27/03/2014')
insert into az values(4, '28/03/2014')
select * from az
Use this Line for your Textbox Field Expression:
=IIF(IsNothing(Fields!Dob.Value),"",Mid(Fields!Dob.Value,7,4) + "-" +
Mid(Fields!Dob.Value,4,2) + "-" + Left(Fields!Dob.Value,2))
DECLARE #DATECOL VARCHAR(13) = '25/01/2015'
-- Date Format
SELECT CAST(RIGHT(#DATECOL,4) + '-' + LEFT(RIGHT(#DATECOL,7),2) + '-' + LEFT(#DATECOL,2) AS DATE)
-- Varchar format
SELECT RIGHT(#DATECOL,4) + '-' + LEFT(RIGHT(#DATECOL,7),2) + '-' + LEFT(#DATECOL,2)
SQL FIDDLE

Count previous occurences of a value split by date ranges

Here's a simple query we do for ad hoc requests from our Marketing department on the leads we received in the last 90 days.
SELECT ID
,FIRST_NAME
,LAST_NAME
,ADDRESS_1
,ADDRESS_2
,CITY
,STATE
,ZIP
,HOME_PHONE
,MOBILE_PHONE
,EMAIL_ADDRESS
,ROW_ADDED_DTM
FROM WEB_LEADS
WHERE ROW_ADDED_DTM BETWEEN #START AND #END
They are asking for more derived columns to be added that show the number of previous occurences of ADDRESS_1 where the EMAIL_ADDRESS matches. But they want is for different date ranges.
So the derived columns would look like this:
,COUNT_ADDRESS_1_LAST_1_DAYS,
,COUNT_ADDRESS_1_LAST_7_DAYS
,COUNT_ADDRESS_1_LAST_14_DAYS
etc.
I've manually filled these derived columns using update statements when there was just a few. The above query is really just a sample of a much larger query with many more columns. The actual request has blossomed into 6 date ranges for 13 columns. I'm asking if there's a better way then using 78 additional update statements.
I think you will have a hard time writing a query that includes all of these 78 metrics per e-mail address without actually creating a query that hard-codes the different choices. However you can generate such a pivot query with dynamic SQL, which will save you some keystrokes and will adjust dynamically as you add more columns to the table.
The result you want to end up with will look something like this (but of course you won't want to type it):
;WITH y AS
(
SELECT
EMAIL_ADDRESS,
/* aggregation portion */
[ADDRESS_1] = COUNT(DISTINCT [ADDRESS_1]),
[ADDRESS_2] = COUNT(DISTINCT [ADDRESS_2]),
... other columns
/* end agg portion */
FROM dbo.WEB_LEADS AS wl
WHERE ROW_ADDED_DTM >= /* one of 6 past dates */
GROUP BY wl.EMAIL_ADDRESS
)
SELECT EMAIL_ADDRESS,
/* pivot portion */
COUNT_ADDRESS_1_LAST_1_DAYS = *count address 1 from 1 day ago*,
COUNT_ADDRESS_1_LAST_7_DAYS = *count address 1 from 7 days ago*,
... other date ranges ...
COUNT_ADDRESS_2_LAST_1_DAYS = *count address 2 from 1 day ago*,
COUNT_ADDRESS_2_LAST_7_DAYS = *count address 2 from 7 days ago*,
... other date ranges ...
... repeat for 11 more columns ...
/* end pivot portion */
FROM y
GROUP BY EMAIL_ADDRESS
ORDER BY EMAIL_ADDRESS;
This is a little involved, and it should all be run as one script, but I'm going to break it up into chunks to intersperse comments on how the above portions are populated without typing them. (And before long #Bluefeet will probably come along with a much better PIVOT alternative.) I'll enclose my interspersed comments in /* */ so that you can still copy the bulk of this answer into Management Studio and run it with the comments intact.
Code/comments to copy follows:
/*
First, let's build a table of dates that can be used both to derive labels for pivoting and to assist with aggregation. I've added the three ranges you've mentioned and guessed at a fourth, but hopefully it is clear how to add more:
*/
DECLARE #d DATE = SYSDATETIME();
CREATE TABLE #L(label NVARCHAR(15), d DATE);
INSERT #L(label, d) VALUES
(N'LAST_1_DAYS', DATEADD(DAY, -1, #d)),
(N'LAST_7_DAYS', DATEADD(DAY, -8, #d)),
(N'LAST_14_DAYS', DATEADD(DAY, -15, #d)),
(N'LAST_MONTH', DATEADD(MONTH, -1, #d));
/*
Next, let's build the portions of the query that are repeated per column name. First, the aggregation portion is just in the format col = COUNT(DISTINCT col). We're going to go to the catalog views to dynamically derive the list of column names (except ID, EMAIL_ADDRESS and ROW_ADDED_DTM) and stuff them into a #temp table for re-use.
*/
SELECT name INTO #N FROM sys.columns
WHERE [object_id] = OBJECT_ID(N'dbo.WEB_LEADS')
AND name NOT IN (N'ID', N'EMAIL_ADDRESS', N'ROW_ADDED_DTM');
DECLARE #agg NVARCHAR(MAX) = N'', #piv NVARCHAR(MAX) = N'';
SELECT #agg += ',
' + QUOTENAME(name) + ' = COUNT(DISTINCT '
+ QUOTENAME(name) + ')' FROM #N;
PRINT #agg;
/*
Next we'll build the "pivot" portion (even though I am angling for the poor man's pivot - a bunch of CASE expressions). For each column name we need a conditional against each range, so we can accomplish this by cross joining the list of column names against our labels table. (And we'll use this exact technique again in the query later to make the /* one of past 6 dates */ portion work.
*/
SELECT #piv += ',
COUNT_' + n.name + '_' + l.label
+ ' = MAX(CASE WHEN label = N''' + l.label
+ ''' THEN ' + QUOTENAME(n.name) + ' END)'
FROM #N as n CROSS JOIN #L AS l;
PRINT #piv;
/*
Now, with those two portions populated as we'd like them, we can build a dynamic SQL statement that fills out the rest:
*/
DECLARE #sql NVARCHAR(MAX) = N';WITH y AS
(
SELECT
EMAIL_ADDRESS, l.label' + #agg + '
FROM dbo.WEB_LEADS AS wl
CROSS JOIN #L AS l
WHERE wl.ROW_ADDED_DTM >= l.d
GROUP BY wl.EMAIL_ADDRESS, l.label
)
SELECT EMAIL_ADDRESS' + #piv + '
FROM y
GROUP BY EMAIL_ADDRESS
ORDER BY EMAIL_ADDRESS;';
PRINT #sql;
EXEC sp_executesql #sql;
GO
DROP TABLE #N, #L;
/*
Now again, this is a pretty complex piece of code, and perhaps it can be made easier with PIVOT. But I think even #Bluefeet will write a version of PIVOT that uses dynamic SQL because there is just way too much to hard-code here IMHO.
*/