This post is a continuation of my pervious articles:
In the last part, I showed how to extract attachments from the emails. In this part, we will see how to execute them in a batch on a number of SQL Server databases.
The Problem
To execute a batch of *.sql files on one or more SQL Server databases uninterrupted, without any human intervention. The sql files are assumed to be named in ascending order of their execution sequence.
The Solution
- Open SQL Server Management Studio.
- Copy and paste the following code in a new SQL file.
USE Master GO -- To allow xp_cmdshell execution. PRINT 'Enabling xp_cmdshell utility...' EXEC sp_configure 'show advanced options', 1 RECONFIGURE EXEC sp_configure 'xp_cmdshell', 1 RECONFIGURE GO DECLARE @ScriptFilesDir VARCHAR(MAX), @Databases VARCHAR(MAX), @ServerName VARCHAR(MAX) -- ****************************************************************************************** -- ***************************** USER CONFIGURABLE VARIABLES ******************************** -- ****************************************************************************************** SET @ScriptFilesDir = 'C:\Temp\Scripts\' --' SET @ServerName = 'Your_SQLServer_Name' SET @Databases = 'Database1, Database2, Database3, Database4, Database5, Database6' -- ****************************************************************************************** DECLARE @FileList Table (FileNumber INT IDENTITY(1,1), FileName VARCHAR(255), Command VARCHAR(MAX)) DECLARE @DatabaseList Table (DBNumber INT IDENTITY(1,1), DBName VARCHAR(MAX)) DECLARE @Command VARCHAR(2048), @Command1 VARCHAR(2048) SET NOCOUNT ON SET @Command = 'ECHO Running Scripts Started %DATE% %TIME% > ' + @ScriptFilesDir + 'Output.txt' EXEC xp_cmdshell @Command, NO_OUTPUT -- Get a list of *.sql files we want to execute on our databases SET @Command = 'DIR /B /O:-N ' + @ScriptFilesDir + '*.sql' INSERT INTO @FileList (FileName) EXEC xp_cmdshell @Command DELETE FROM @FileList WHERE FileName IS NULL OR FileName NOT LIKE '%.sql' UPDATE @FileList SET Command = 'sqlcmd -S ' + @ServerName + ' -d %DATABASE% -i "' + @ScriptFilesDir + FileName + '" >> ' + @ScriptFilesDir + 'Output.txt' -- Create a list of databases to work upon DECLARE @BeginPos INT, @NextPos INT, @SubStrLen INT SELECT @BeginPos = 0, @NextPos = 1 WHILE @NextPos > 0 BEGIN SET @NextPos = CHARINDEX(',', @Databases, @BeginPos + 1) SET @SubStrLen = CASE WHEN @NextPos > 0 THEN @NextPos ELSE LEN(@Databases) + 1 END - @BeginPos - 1 INSERT INTO @DatabaseList (DBName) VALUES (LTRIM(RTRIM((SUBSTRING(@Databases , @BeginPos + 1, @SubStrLen))))) SET @BeginPos = @NextPos END -- Run the script files one by one on each of the specified databases PRINT '' PRINT 'Running Scripts...' DECLARE @DBName VARCHAR(255), @DbNumber INT, @FileName VARCHAR(255), @FileNumber INT SELECT @FileNumber = MAX(FileNumber) FROM @FileList WHILE (@FileNumber > 0) BEGIN SELECT @FileNumber = @FileNumber - 1, @FileName = FileName, @Command = Command FROM @FileList WHERE FileNumber = @FileNumber RAISERROR (' Executing file %s',0, 1, @FileName) WITH NOWAIT SET @Command1 = 'ECHO ' + @FileName + ': >> ' + @ScriptFilesDir + 'Output.txt' EXEC xp_cmdshell @Command1, NO_OUTPUT SELECT @DbNumber = MAX(DbNumber) FROM @DatabaseList WHILE @DbNumber > 0 BEGIN SELECT @DbNumber = @DbNumber - 1, @DBName = DBName FROM @DatabaseList WHERE DbNumber = @DbNumber --RAISERROR (' %s',0, 1, @DBName) WITH NOWAIT SET @Command1 = REPLACE(@Command, '%DATABASE%', @DBName) EXEC xp_cmdshell @Command1, NO_OUTPUT END END PRINT 'Running Scripts Complete' PRINT '' -- Show the program output & errors on the screen. DECLARE @OutputTable Table (Output VARCHAR(MAX)) SET @Command = 'type "' + @ScriptFilesDir + 'Output.txt"' INSERT INTO @OutputTable EXEC xp_cmdshell @Command SELECT * FROM @OutputTable WHERE Output IS NOT NULL SET @Command = 'ECHO Running Scripts Completed %DATE% %TIME% >> ' + @ScriptFilesDir + 'Output.txt' EXEC xp_cmdshell @Command, NO_OUTPUT GO -- To disable xp_cmdshell again once we are thru with our work. PRINT 'Disabling xp_cmdshell utility...' EXEC sp_configure 'xp_cmdshell', 0 RECONFIGURE EXEC sp_configure 'show advanced options', 0 RECONFIGURE GO PRINT '' PRINT 'Check the Output.txt file for intermediate output and errors.' GO
- Modify the code and set the variables appropriately.
@ScriptFilesDir: The folder path where your script files are located.@ServerName: The name of your SQL Server instance.
@Databases: A comma separated list of databases, on which the scripts should run.
- Save this file somewhere on your disk (for future use).
- Press F5 key or click the Execute button to run the script.
- Switch over to the Messages tab to see the current status of the script run. Wait for the script to finish execution.
- Once the script has finished execution, you can view the result of execution and any errors in the Output.txt file. This is created in the @ScriptFilesDir folder
Enjoy! 🙂
Further Developments
This script was meant for my personal use. So I didn’t care much about packaging it nicely/properly, maybe into a Stored Procedure etc. I’m comfortable opening this SQL script file everytime I need it, and click the Execute button.
However if you want to implement the solution on a professional level (e.g. within your organization etc.), then you may consider modifying the script and converting it into Stored Procedures etc. or develop a front-end application for this.
Previous Parts:
April 6, 2012 at 7:51 am
I truly wanted to write down a quick remark to thank you for these pleasant secrets you are showing at this website. My time-consuming internet lookup has at the end been rewarded with really good know-how to go over with my contacts. I ‘d express that we readers actually are undoubtedly blessed to dwell in a fantastic community with many outstanding individuals with insightful concepts. I feel rather grateful to have used the web site and look forward to tons of more cool times reading here. Thank you once more for all the details.
April 10, 2012 at 6:52 am
how do you display the actual results of this query to the screen?
April 10, 2012 at 8:54 am
When the query is running, if you switch over to the “Messages” tab, you can see the current status.
When the query has finished executing, the result is displayed in the “Results” tab.
The results are also saved to a file on disk. You can open the “C:\Temp\Scripts\Output.txt” file (if you didn’t change the @ScriptFilesDir variable in the script) to view the results.
Please have a look at the video link in the first part of this article. It should make the things clear to you.
February 27, 2013 at 8:44 pm
Very good script. Saved me lots of time. Thanks!!!
April 28, 2013 at 5:22 am
Hello! Someone in my Myspace group shared this website with us so I came to check it out.
I’m definitely loving the information. I’m book-marking and will
be tweeting this to my followers! Outstanding blog and amazing design.
April 29, 2013 at 3:49 pm
This is my first time go to see at here and i am genuinely pleassant to read everthing at
alone place.
May 9, 2013 at 7:26 pm
Seems to be a nice exercise, but the following works without writing any code or opening your servers to a security risk:
http://msdn.microsoft.com/en-us/library/bb964743(v=sql.100).aspx
Documented risk:
http://msdn.microsoft.com/en-us/library/ms175046.aspx
July 18, 2013 at 11:31 am
Not relevant to what he is trying to accomplish. Did you read the links you posted?
June 3, 2013 at 12:29 am
You actually make it seem so easy with your presentation but I find this
matter to be really one thing that I feel I would never understand.
It sort of feels too complex and very broad for
me. I am taking a look ahead to your subsequent put up, I will try to get the cling of it!
July 18, 2013 at 12:25 pm
If you would like to improve your familiarity just keep visiting this website
and be updated with the most up-to-date news posted here.
November 14, 2013 at 2:04 pm
Hi Pradeep,
Really appreciate your work and help, please help out for, i have executed the script i am getting the output as ‘Access is Denied’.
November 15, 2013 at 7:56 am
Check that the user with which you logged in has adequate privileges. I was logged in as “sa” user while building and testing the script, so didn’t have any problems.
November 15, 2013 at 10:25 am
I have also tried with “sa” user, but same result ‘Access is Denied’.
And is that necessary to create proxy account to execute this script.?
November 15, 2013 at 1:59 pm
I can think of a few things, though not sure if these would be useful.
1. The physical folder specified by @ScriptFilesDir (‘C:\Temp\Scripts\’ in my case) may not have adequate read/write permissions.
2. Possibly your sql files are not on the server drive. The drive specified @ScriptFilesDir path is the harddisk drive on SQL Server machine.
Can you experiment around and see which line of code is failing? That might give more clues. You can do that by selecting text from beginning to a few lines and pressing F5 key. If that works, then extend the selection to a few more lines and repeat until you can pinpoint the failing line of code.
November 18, 2013 at 6:26 am
Hi Pradeep,
— Show the program output & errors on the screen.
1 DECLARE @OutputTable Table (Output VARCHAR(MAX))
2 SET @Command = ‘type “‘ + @ScriptFilesDir + ‘Output.txt”‘
3 INSERT INTO @OutputTable EXEC xp_cmdshell @Command
4 SELECT * FROM @OutputTable WHERE Output IS NOT NULL
5 SET @Command = ‘ECHO Running Scripts Completed %DATE% %TIME% >> ‘ + @ScriptFilesDir + ‘Output.txt’
6 EXEC xp_cmdshell @Command, NO_OUTPUT
Its at line number 4 in above set of line giving me ‘Access is denied’. Except that line all other lines are executed….
November 18, 2013 at 6:29 am
In this page or blog above that is @ line number 77, its showing ‘Access is Denied’.
November 18, 2013 at 7:27 am
There is some problem with the folder to which @ScriptFilesDir points to.
Try the following:
1. Ensure that the path set in @ScriptFilesDir ends with a “\”. e.g. It should be ‘C:\Temp\Scripts\’ but not ‘C:\Temp\Scripts’
2. Ensure that the folder to which @ScriptFilesDir points has write permissions. This is required to write the output log to a file.
November 18, 2013 at 8:00 am
Thanks for patience and reply, yes path is perfect and permission is full control (i.e read , write etc) all permissions.
November 18, 2013 at 10:50 am
Hi Pradeep,
Thanks for your suggestions, finally done, set folder permissions to everyone it worked.
May 1, 2014 at 8:09 pm
Excellent work.
September 26, 2014 at 8:20 am
[…] Executing a set of SQL Script Files (*.sql) on a Group of SQL Server Databases […]
September 14, 2015 at 6:39 am
dear pradeep
great post , i have one small clarification while i converting the above script into sp i am getting error RECONFIGURE GO . how to handle this ?
October 7, 2015 at 9:34 pm
Hello my friend! I want to say that this post is amazing,
great written and include almost all important infos. I would
like to peer extra posts like this .
October 27, 2017 at 8:56 am
[…] Executing a set of SQL Script Files (*.sql) on a Group of SQL Server Databases […]
February 2, 2018 at 1:03 am
[…] Executing a set of SQL Script Files (*.sql) on a Group of SQL Server Databases […]
February 3, 2018 at 2:48 am
[…] Executing a set of SQL Script Files (*.sql) on a Group of SQL Server Databases […]
April 16, 2018 at 10:20 am
[…] Executing a set of SQL Script Files (*.sql) on a Group of SQL Server Databases […]